Advertisement
Guest User

Untitled

a guest
Apr 22nd, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.82 KB | None | 0 0
  1. #![deny(
  2. elided_lifetimes_in_paths,
  3. )]
  4.  
  5. #![allow(
  6. dead_code,
  7. )]
  8.  
  9. // 0.4.6
  10. use ::chrono::*;
  11.  
  12. mod lib {
  13. use core::{*,
  14. marker::PhantomPinned as PinSensitive,
  15. pin::Pin,
  16. };
  17.  
  18. #[derive(Debug)]
  19. pub
  20. struct Location {
  21. pub
  22. name: String,
  23. }
  24.  
  25. #[repr(transparent)]
  26. pub
  27. struct PinSensitiveLocation {
  28. location: Location,
  29. _pin_sensitive: PinSensitive,
  30. }
  31.  
  32. impl ops::Deref for PinSensitiveLocation {
  33. type Target = Location;
  34.  
  35. fn deref (self: &'_ Self) -> &'_ Self::Target
  36. {
  37. &self.location
  38. }
  39. }
  40.  
  41. impl fmt::Debug for PinSensitiveLocation {
  42. fn fmt (
  43. self: &'_ Self,
  44. stream: &'_ mut fmt::Formatter<'_>,
  45. ) -> fmt::Result
  46. {
  47. // write!(stream, "PinSensitive")?;
  48. fmt::Debug::fmt(&self.location, stream)
  49. }
  50. }
  51.  
  52. #[derive(Debug)]
  53. pub
  54. struct Locations /* = */ (
  55. pub
  56. Vec<Location>
  57. );
  58.  
  59. #[derive(Debug)]
  60. pub
  61. struct PinnedLocations /* = */ (
  62. Pin<Box< [PinSensitiveLocation] >>
  63. );
  64.  
  65. impl PinnedLocations {
  66. pub
  67. fn get (
  68. self: &'_ Self,
  69. index: usize,
  70. ) -> Option< Pin<&'_ PinSensitiveLocation> >
  71. {
  72. if index < self.0.len() {
  73. Some(unsafe {
  74. // safety: index / field access is a valid pin projection
  75. self.0
  76. .as_ref()
  77. .map_unchecked(move |locations| locations.get_unchecked(index))
  78. })
  79. } else {
  80. None
  81. }
  82. }
  83. }
  84.  
  85. impl Locations {
  86. pub
  87. fn pinned (self: Self) -> PinnedLocations
  88. {
  89. let mut boxed_locations: Box<[Location]> = self.0.into_boxed_slice();
  90. let pinned_locations: Box<[PinSensitiveLocation]> = unsafe {
  91. // Safety: PinSensitiveLocation is #[repr(transparent)]
  92. let (len, ptr): (usize, *mut PinSensitiveLocation) = (
  93. boxed_locations.len(),
  94. boxed_locations.as_mut_ptr() as *mut PinSensitiveLocation,
  95. );
  96. mem::forget(boxed_locations);
  97. Box::from_raw(
  98. slice::from_raw_parts_mut(
  99. ptr,
  100. len,
  101. )
  102. )
  103. };
  104. PinnedLocations(pinned_locations.into())
  105. }
  106. }
  107.  
  108. #[derive(Debug)]
  109. pub
  110. struct Event<'loc> {
  111. pub
  112. name: String,
  113.  
  114. pub
  115. occurrences: Vec<Occurrence<'loc>>,
  116. }
  117.  
  118. #[derive(
  119. Debug,
  120. // ensures there is no drop glue:
  121. // `WithEvents` transmute requires that the &'loc reference must not be dereferenced when dropped
  122. Clone, Copy,
  123. )]
  124. pub
  125. struct Occurrence<'loc> {
  126. pub
  127. start: ::chrono::NaiveDateTime,
  128.  
  129. pub
  130. location: Pin<&'loc PinSensitiveLocation>,
  131. }
  132.  
  133. #[derive(Debug)]
  134. pub
  135. struct Store {
  136. pub
  137. locations: PinnedLocations,
  138.  
  139. events: Vec<Event<'static>>,
  140. }
  141.  
  142. impl Store {
  143. pub
  144. fn events (
  145. self: &'_ Self,
  146. ) -> &'_ Vec<Event<'_>>
  147. {
  148. &self.events
  149. }
  150.  
  151. /// API to allow mutation and adding events
  152. /// (reconstructing the Store is needed)
  153. pub
  154. fn get_locations_and_take_events (
  155. self: &'_ mut Self,
  156. ) -> (&'_ PinnedLocations, Vec<Event<'_>>)
  157. {
  158. (&self.locations, mem::replace(&mut self.events, Vec::default()))
  159. }
  160. }
  161.  
  162. impl Store {
  163. pub
  164. fn with_events (
  165. events: Vec<Event<'_>>,
  166. ) -> WithEvents
  167. {
  168. // safety:
  169. // - no public non-`unsafe` API
  170. // - Event : Copy thus drop does not deref
  171. unsafe {
  172. WithEvents(mem::transmute(events))
  173. }
  174. }
  175. }
  176.  
  177. pub
  178. struct WithEvents /* = */ (
  179. /// has to be private
  180. Vec<Event<'static>>
  181. );
  182. impl WithEvents {
  183. /// # Safety
  184. ///
  185. /// the given `events` must refer to the input `locations` only
  186. pub
  187. unsafe fn and_locations (
  188. self: Self,
  189. locations: PinnedLocations,
  190. ) -> Store
  191. {
  192. let WithEvents(events) = self;
  193. Store {
  194. locations,
  195. events,
  196. }
  197. }
  198. }
  199. }
  200. use lib::*;
  201.  
  202. fn main ()
  203. {
  204. let bar = Location {
  205. name: String::from("Some bar"),
  206. };
  207. let foo = Location {
  208. name: String::from("Some foo"),
  209. };
  210. let locations = Locations(vec![bar, foo]).pinned();
  211. let events = vec![Event {
  212. name: "Social Dance".into(),
  213. occurrences: vec![Occurrence {
  214. start: NaiveDate::from_ymd(2019, 4, 1).and_hms(20, 30, 00),
  215. location: locations.get(0).unwrap(),
  216. }],
  217. }];
  218. let mut store = unsafe {
  219. // safety: it is indeed from `locations` that `events` does borrow
  220. Store::with_events(events)
  221. .and_locations(locations)
  222. };
  223. dbg!(&store);
  224.  
  225. // Adding an event afterwards
  226. let (locations, mut events) = store.get_locations_and_take_events();
  227. let start = NaiveDate::from_ymd(2019, 4, 1).and_hms(20, 30, 00);
  228. events.push(Event {
  229. name: "Pin-pong".into(),
  230. occurrences: vec![
  231. Occurrence { start, location: locations.get(0).unwrap(), },
  232. Occurrence { start, location: locations.get(1).unwrap(), },
  233. ],
  234. });
  235. let store_events = Store::with_events(events);
  236. let Store { locations, .. } = store;
  237. let store = unsafe {
  238. // safety: it is indeed from `locations` that `events` does borrow
  239. store_events.and_locations(locations)
  240. };
  241. dbg!(&store);
  242. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement