SHARE
TWEET

Untitled

a guest Feb 16th, 2019 75 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.                   let tracked = entry.downcast_ref::<Tracked<SomeEntity>>().unwrap();
  49.                 println!(
  50.                     "The frist entry will be \"{}\" to db: \n{:?}",
  51.                     if *tracked.state() == State::Added {"added"} else {"updated"},
  52.                     tracked
  53.                 );
  54.             } else if key == _some_other_entity_type {
  55.                 // still, we know the type...
  56.                 let tracked = entry.downcast_ref::<Tracked<SomeOtherEntity>>().unwrap();
  57.                 println!(
  58.                     "The other entry will be \"{}\" to db: \n{:?}",
  59.                     if *tracked.state() == State::Added {"added"} else {"updated"},
  60.                     tracked
  61.                 );
  62.             }
  63.         }
  64.         // ------- COMMIT TRANSACTION --------
  65.     }
  66. }
  67.  
  68. #[derive(Debug)]
  69. struct Tracked<T> {
  70.     id: usize,
  71.     inner: T,
  72.     state: State,
  73. }
  74.  
  75. impl<T> Tracked<T> {
  76.     fn new(id: usize, inner: T, state: State) -> Self {
  77.         Tracked { id, inner, state }
  78.     }
  79.  
  80.     fn value(&mut self) -> &mut T {
  81.         &mut self.inner
  82.     }
  83.  
  84.     fn state(&self) -> &State {
  85.         &self.state
  86.     }
  87. }
  88.  
  89. #[derive(Debug)]
  90. struct SomeRepo<T> {
  91.     _marker: PhantomData<T>,
  92. }
  93.  
  94. impl<T: Entity> SomeRepo<T> {
  95.     fn new() -> Self {
  96.         SomeRepo {
  97.             _marker: PhantomData,
  98.         }
  99.     }
  100.     fn get_by_id(&self, id: i32) -> T {
  101.         // get from db
  102.         T::new(id)
  103.     }
  104. }
  105.  
  106. trait Entity {
  107.     fn new(id: i32) -> Self;
  108. }
  109.  
  110. #[derive(Debug, PartialEq)]
  111. enum State {
  112.     Added,
  113.     Dirty,
  114.     //...
  115. }
  116.  
  117. #[derive(Debug)]
  118. struct SomeEntity {
  119.     pub id: i32,
  120.     pub msg: String,
  121. }
  122.  
  123. impl Entity for SomeEntity {
  124.     fn new(id: i32) -> Self {
  125.         SomeEntity {
  126.             id,
  127.             msg: String::from("Hello"),
  128.         }
  129.     }
  130. }
  131.  
  132. #[derive(Debug)]
  133. struct SomeOtherEntity {
  134.     pub id: i32,
  135.     pub msg: String,
  136. }
  137.  
  138. impl Entity for SomeOtherEntity {
  139.     fn new(id: i32) -> Self {
  140.         SomeOtherEntity {
  141.             id,
  142.             msg: String::from("Other hello"),
  143.         }
  144.     }
  145. }
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