daily pastebin goal
34%
SHARE
TWEET

Untitled

a guest Feb 16th, 2019 55 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. fn main() {
  2.     let mut session = UoW::new();
  3.     let entry = session.load::<SomeEntity>();
  4.     println!("{:?}", entry);
  5.     entry.value().msg = "Changed".to_string();
  6.     println!("{:?}", entry);
  7.  
  8.     let other_entry = session.load::<SomeOtherEntity>();
  9.     other_entry.value().msg = "Other has also changed".to_string();
  10.  
  11.     session.commit();
  12. }
  13.  
  14. use std::any::{Any, TypeId};
  15. use std::marker::PhantomData;
  16. #[derive(Debug)]
  17. struct UoW {
  18.     tracked: Vec<(TypeId, Box<Any>)>,
  19. }
  20.  
  21. impl<'a> UoW {
  22.     fn new() -> Self {
  23.         UoW { tracked: vec![] }
  24.     }
  25.  
  26.     fn load<T: Any + Entity + 'a>(&mut self) -> &mut Tracked<T> {
  27.         let t = TypeId::of::<T>();
  28.         let index = self.tracked.len();
  29.  
  30.         // Let's pretend we get from the database
  31.         let repo = SomeRepo::new();
  32.         let entry: T = repo.get_by_id(1);
  33.  
  34.         self.tracked
  35.             .push((t, Box::new(Tracked::new(index, entry, State::Dirty))));
  36.         let y = &mut self.tracked[index].1;
  37.         // should be safe to unwrap since we know it's of type T
  38.         y.downcast_mut::<Tracked<T>>().unwrap()
  39.     }
  40.  
  41.     fn commit(&mut self) {
  42.         let _some_entity_type = TypeId::of::<SomeEntity>();
  43.         let _some_other_entity_type = TypeId::of::<SomeOtherEntity>();
  44.  
  45.         // -------- START TRANSACTION --------
  46.         for (key, entry) in self.tracked.drain(..) {
  47.             if key == _some_entity_type {
  48.                 // still, we know the type, unwrap should be safe enough for now...
  49.                 let tracked = entry.downcast_ref::<Tracked<SomeEntity>>().unwrap();
  50.                 println!(
  51.                     "The frist entry will be \"{}\" to db: \n{:?}",
  52.                     if *tracked.state() == State::Added {"added"} else {"updated"},
  53.                     tracked
  54.                 );
  55.             } else if key == _some_other_entity_type {
  56.                 // still, we know the type, unwrap should be safe enough for now...
  57.                 let tracked = entry.downcast_ref::<Tracked<SomeOtherEntity>>().unwrap();
  58.                 println!(
  59.                     "The other entry will be \"{}\" to db: \n{:?}",
  60.                     if *tracked.state() == State::Added {"added"} else {"updated"},
  61.                     tracked
  62.                 );
  63.             }
  64.         }
  65.         // ------- COMMIT TRANSACTION --------
  66.     }
  67. }
  68.  
  69. #[derive(Debug)]
  70. struct Tracked<T> {
  71.     id: usize,
  72.     inner: T,
  73.     state: State,
  74. }
  75.  
  76. impl<T> Tracked<T> {
  77.     fn new(id: usize, inner: T, state: State) -> Self {
  78.         Tracked { id, inner, state }
  79.     }
  80.  
  81.     fn value(&mut self) -> &mut T {
  82.         &mut self.inner
  83.     }
  84.  
  85.     fn state(&self) -> &State {
  86.         &self.state
  87.     }
  88. }
  89.  
  90. #[derive(Debug)]
  91. struct SomeRepo<T> {
  92.     _marker: PhantomData<T>,
  93. }
  94.  
  95. impl<T: Entity> SomeRepo<T> {
  96.     fn new() -> Self {
  97.         SomeRepo {
  98.             _marker: PhantomData,
  99.         }
  100.     }
  101.     fn get_by_id(&self, id: i32) -> T {
  102.         // get from db
  103.         T::new(id)
  104.     }
  105. }
  106.  
  107. trait Entity {
  108.     fn new(id: i32) -> Self;
  109. }
  110.  
  111. #[derive(Debug, PartialEq)]
  112. enum State {
  113.     Added,
  114.     Dirty,
  115.     //...
  116. }
  117.  
  118. #[derive(Debug)]
  119. struct SomeEntity {
  120.     pub id: i32,
  121.     pub msg: String,
  122. }
  123.  
  124. impl Entity for SomeEntity {
  125.     fn new(id: i32) -> Self {
  126.         SomeEntity {
  127.             id,
  128.             msg: String::from("Hello"),
  129.         }
  130.     }
  131. }
  132.  
  133. #[derive(Debug)]
  134. struct SomeOtherEntity {
  135.     pub id: i32,
  136.     pub msg: String,
  137. }
  138.  
  139. impl Entity for SomeOtherEntity {
  140.     fn new(id: i32) -> Self {
  141.         SomeOtherEntity {
  142.             id,
  143.             msg: String::from("Other hello"),
  144.         }
  145.     }
  146. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top