Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- fn main() {
- let mut session = UoW::new();
- let entry = session.load::<SomeEntity>();
- println!("{:?}", entry);
- entry.value().msg = "Changed".to_string();
- println!("{:?}", entry);
- let other_entry = session.load::<SomeOtherEntity>();
- other_entry.value().msg = "Other has also changed".to_string();
- session.commit();
- }
- use std::any::{Any, TypeId};
- use std::marker::PhantomData;
- #[derive(Debug)]
- struct UoW {
- tracked: Vec<(TypeId, Box<Any>)>,
- }
- impl<'a> UoW {
- fn new() -> Self {
- UoW { tracked: vec![] }
- }
- fn load<T: Any + Entity + 'a>(&mut self) -> &mut Tracked<T> {
- let t = TypeId::of::<T>();
- let index = self.tracked.len();
- // Let's pretend we get from the database
- let repo = SomeRepo::new();
- let entry: T = repo.get_by_id(1);
- self.tracked
- .push((t, Box::new(Tracked::new(index, entry, State::Dirty))));
- let y = &mut self.tracked[index].1;
- // should be safe to unwrap since we know it's of type T
- y.downcast_mut::<Tracked<T>>().unwrap()
- }
- fn commit(&mut self) {
- let _some_entity_type = TypeId::of::<SomeEntity>();
- let _some_other_entity_type = TypeId::of::<SomeOtherEntity>();
- // -------- START TRANSACTION --------
- for (key, entry) in self.tracked.drain(..) {
- if key == _some_entity_type {
- // still, we know the type, unwrap should be safe enough for now...
- let tracked = entry.downcast_ref::<Tracked<SomeEntity>>().unwrap();
- println!(
- "The frist entry will be \"{}\" to db: \n{:?}",
- if *tracked.state() == State::Added {"added"} else {"updated"},
- tracked
- );
- } else if key == _some_other_entity_type {
- // still, we know the type, unwrap should be safe enough for now...
- let tracked = entry.downcast_ref::<Tracked<SomeOtherEntity>>().unwrap();
- println!(
- "The other entry will be \"{}\" to db: \n{:?}",
- if *tracked.state() == State::Added {"added"} else {"updated"},
- tracked
- );
- }
- }
- // ------- COMMIT TRANSACTION --------
- }
- }
- #[derive(Debug)]
- struct Tracked<T> {
- id: usize,
- inner: T,
- state: State,
- }
- impl<T> Tracked<T> {
- fn new(id: usize, inner: T, state: State) -> Self {
- Tracked { id, inner, state }
- }
- fn value(&mut self) -> &mut T {
- &mut self.inner
- }
- fn state(&self) -> &State {
- &self.state
- }
- }
- #[derive(Debug)]
- struct SomeRepo<T> {
- _marker: PhantomData<T>,
- }
- impl<T: Entity> SomeRepo<T> {
- fn new() -> Self {
- SomeRepo {
- _marker: PhantomData,
- }
- }
- fn get_by_id(&self, id: i32) -> T {
- // get from db
- T::new(id)
- }
- }
- trait Entity {
- fn new(id: i32) -> Self;
- }
- #[derive(Debug, PartialEq)]
- enum State {
- Added,
- Dirty,
- //...
- }
- #[derive(Debug)]
- struct SomeEntity {
- pub id: i32,
- pub msg: String,
- }
- impl Entity for SomeEntity {
- fn new(id: i32) -> Self {
- SomeEntity {
- id,
- msg: String::from("Hello"),
- }
- }
- }
- #[derive(Debug)]
- struct SomeOtherEntity {
- pub id: i32,
- pub msg: String,
- }
- impl Entity for SomeOtherEntity {
- fn new(id: i32) -> Self {
- SomeOtherEntity {
- id,
- msg: String::from("Other hello"),
- }
- }
- }
Add Comment
Please, Sign In to add comment