ddd_rs/infrastructure/memory/
repository.rs

1use std::collections::HashMap;
2
3use crate::application::{ReadRepository, Repository};
4use crate::domain::{AggregateRoot, Entity};
5
6/// An in-memory implementation of [Repository], using a [HashMap].
7///
8/// See the example on [Repository] for usage information of this repository implementation.
9pub struct InMemoryRepository<T: AggregateRoot> {
10    entities: std::sync::RwLock<HashMap<<T as Entity>::Id, T>>,
11}
12
13impl<T: AggregateRoot> InMemoryRepository<T> {
14    /// Creates a new [InMemoryRepository].
15    pub fn new() -> Self {
16        Self {
17            entities: std::sync::RwLock::new(HashMap::new()),
18        }
19    }
20}
21
22impl<T: AggregateRoot> Default for InMemoryRepository<T> {
23    fn default() -> Self {
24        Self::new()
25    }
26}
27
28#[async_trait::async_trait]
29impl<T: AggregateRoot + Clone> ReadRepository<T> for InMemoryRepository<T>
30where
31    <T as Entity>::Id: std::hash::Hash + Eq,
32{
33    async fn get_by_id(&self, id: <T as Entity>::Id) -> crate::Result<Option<T>> {
34        let ro_entities = self.entities.read().unwrap();
35
36        let entity = ro_entities.get(&id).cloned();
37
38        Ok(entity)
39    }
40
41    async fn list(&self, skip: usize, take: usize) -> crate::Result<Vec<T>> {
42        let ro_entities = self.entities.read().unwrap();
43
44        let entities = ro_entities
45            .values()
46            .skip(skip)
47            .take(take)
48            .cloned()
49            .collect();
50
51        Ok(entities)
52    }
53
54    async fn count(&self) -> crate::Result<usize> {
55        let ro_entities = self.entities.read().unwrap();
56
57        Ok(ro_entities.len())
58    }
59}
60
61#[async_trait::async_trait]
62impl<T: AggregateRoot + Clone> Repository<T> for InMemoryRepository<T>
63where
64    <T as Entity>::Id: std::hash::Hash + Eq,
65{
66    async fn add(&self, entity: T) -> crate::Result<T> {
67        let mut wo_entities = self.entities.write().unwrap();
68
69        wo_entities.insert(entity.id().clone(), entity.clone());
70
71        Ok(entity)
72    }
73
74    async fn update(&self, entity: T) -> crate::Result<T> {
75        self.add(entity).await
76    }
77
78    async fn delete(&self, entity: T) -> crate::Result<()> {
79        let mut wo_entities = self.entities.write().unwrap();
80
81        wo_entities.remove(entity.id());
82
83        Ok(())
84    }
85}