Guest User

Untitled

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