Skip to main content

nestforge_core/
store.rs

1use std::sync::{Arc, RwLock};
2
3/*
4Identifiable = tiny trait for entities that have an id
5This lets the framework store handle ID assignment and lookups.
6*/
7pub trait Identifiable {
8    fn id(&self) -> u64;
9    fn set_id(&mut self, id: u64);
10}
11
12/*
13InMemoryStore<T> = framework-provided shared in-memory storage.
14
15This hides Arc/RwLock and gives clean CRUD-ish methods for simple apps,
16examples, and CLI scaffolds.
17*/
18#[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    /*
51    create():
52    - auto-generates next id
53    - stores item
54    - returns stored item
55    */
56    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    /*
67    update_by_id():
68    - mutates item in place via closure
69    - returns updated item
70    */
71    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}