rstdev_domain/
repository.rs

1use std::fmt::Debug;
2
3use crate::types::BaseError;
4use crate::entity::UID;
5
6/// `Repository` is an trait abstraction used for `Repository Pattern` 
7pub trait Repository {
8    type Entity: Debug + Clone;
9    type UIDType: UID;
10
11    fn find_by_uid(&self, uid: Self::UIDType) -> Result<Self::Entity, BaseError>;
12    fn create(&mut self, entity: Self::Entity) -> Result<(), BaseError>;
13    fn update_by_uid(&mut self, uid: Self::UIDType, entity: Self::Entity) -> Result<(), BaseError>;
14    fn remove_by_uid(&mut self, uid: Self::UIDType) -> Result<(), BaseError>;
15}
16
17#[cfg(test)]
18mod tests {
19    use std::collections::HashMap;
20    use std::string::ToString;
21
22    use super::*;
23
24    use rst_common::standard::uuid;
25
26    #[derive(Debug, Clone)]
27    struct FakeUID {
28        uid: String
29    }
30
31    impl FakeUID {
32        fn new() -> Self {
33            let uid = uuid::Uuid::new_v4();            
34            Self { uid: uid.to_string() }
35        }
36    }
37
38    impl ToString for FakeUID {
39        fn to_string(&self) -> String {
40            self.uid.to_owned()
41        }
42    }
43
44    impl UID for FakeUID {
45        type Value = String;
46
47        fn uid(&self) -> Self::Value {
48            self.uid.clone()
49        }
50    }
51
52    #[derive(Debug, Clone)]
53    struct FakeEntity {
54        uid: FakeUID
55    }
56
57    impl FakeEntity {
58        fn new() -> Self {
59            let uid = FakeUID::new();
60            Self { uid }
61        }
62    }
63
64    struct FakeRepo {
65        db: HashMap<String, FakeEntity>
66    }
67
68    impl FakeRepo {
69        fn new() -> Self {
70            let db: HashMap<String, FakeEntity> = HashMap::new();
71            Self { db }
72        }
73    }
74
75    impl Repository for FakeRepo {
76        type Entity = FakeEntity;
77        type UIDType = FakeUID;
78
79        fn find_by_uid(&self, uid: Self::UIDType) -> Result<Self::Entity, BaseError> {
80            let get_entity = self.db.get(&uid.uid());
81            match get_entity {
82                Some(ent) => Ok(ent.clone()),
83                None => Err(BaseError::RepositoryError("entity not found".to_string())) 
84            }
85        }
86
87        fn remove_by_uid(&mut self, uid: Self::UIDType) -> Result<(), BaseError> {
88            self.db.remove(&uid.uid());
89            Ok(())
90        }
91
92        fn create(&mut self, entity: Self::Entity) -> Result<(), BaseError> {
93            self.db.insert(entity.uid.uid.to_string(), entity);
94            Ok(())
95        }
96
97        fn update_by_uid(&mut self, uid: Self::UIDType, entity: Self::Entity) -> Result<(), BaseError> {
98            self.db.insert(uid.to_string(), entity);
99            Ok(())
100        }
101    }
102
103    #[test]
104    fn test_build_repo() {
105        let mut repo = FakeRepo::new();
106        let entity = FakeEntity::new();
107
108        let _ = repo.create(entity.clone());
109        let entity_loaded = repo.find_by_uid(entity.clone().uid);
110        assert!(!entity_loaded.is_err());
111
112        let entity2 = entity_loaded.unwrap();
113        assert_eq!(entity.uid.uid().to_owned(), entity2.uid.uid().to_owned());
114
115        let _ = repo.remove_by_uid(entity.clone().uid);
116        let find_entity = repo.find_by_uid(entity.clone().uid);
117        assert!(find_entity.is_err());
118        assert!(matches!(find_entity.unwrap_err(), BaseError::RepositoryError(_)))
119    }
120}