Guest User

Untitled

a guest
Feb 16th, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.46 KB | None | 0 0
  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. }
Add Comment
Please, Sign In to add comment