1use std::sync::{Arc, RwLock};
2
3pub trait Identifiable {
8 fn id(&self) -> u64;
9 fn set_id(&mut self, id: u64);
10}
11
12#[derive(Clone)]
19pub struct InMemoryStore<T> {
20 items: Arc<RwLock<Vec<T>>>,
21}
22
23impl<T> InMemoryStore<T>
24where
25 T: Identifiable + Clone,
26{
27 pub fn new() -> Self {
28 Self {
29 items: Arc::new(RwLock::new(Vec::new())),
30 }
31 }
32
33 pub fn with_seed(seed: Vec<T>) -> Self {
34 Self {
35 items: Arc::new(RwLock::new(seed)),
36 }
37 }
38
39 pub fn find_all(&self) -> Vec<T> {
40 self.items.read().map(|items| items.clone()).unwrap_or_default()
41 }
42
43 pub fn find_by_id(&self, id: u64) -> Option<T> {
44 self.items
45 .read()
46 .ok()
47 .and_then(|items| items.iter().find(|item| item.id() == id).cloned())
48 }
49
50 pub fn create(&self, mut item: T) -> T {
57 let mut items = self.items.write().expect("store write lock poisoned");
58
59 let next_id = items.iter().map(|item| item.id()).max().unwrap_or(0) + 1;
60 item.set_id(next_id);
61
62 items.push(item.clone());
63 item
64 }
65
66 pub fn update_by_id<F>(&self, id: u64, mut updater: F) -> Option<T>
72 where
73 F: FnMut(&mut T),
74 {
75 let mut items = self.items.write().ok()?;
76 let item = items.iter_mut().find(|item| item.id() == id)?;
77
78 updater(item);
79 Some(item.clone())
80 }
81}