rusty_store/
manager.rs

1use crate::storage::{Storage, StoreError, StoreHandle, Storing};
2
3/// `StoreManager` manages the lifecycle of a store within a specified `Storage` backend. It handles reading and writing store data, as well as providing mutable access to the store's contents.
4///
5/// The `StoreManager` is designed to work with any type that implements the `Storing` trait, allowing it to manage different kinds of store data structures. It abstracts away the complexity of directly interacting with the storage backend, providing an easy-to-use API for managing and persisting store data.
6///
7///
8///
9/// ## Example
10///
11/// ```rust
12/// use serde::{Deserialize, Serialize};
13/// use storage::{StoreManager, Storing};
14///
15/// #[derive(Serialize, Deserialize, Default, Storing)]
16/// pub struct MyStore {
17///     pub count: u32,
18/// }
19///
20/// let storage = Storage::new("APP_ID");
21///
22/// // Create a StoreManager for managing the store data
23/// let mut manager = StoreManager::<MyStore>::new(&storage, "my_store_id")
24///        .expect("Failed to create StoreManager");
25///
26/// // Get a mutable reference to the store
27/// let counter = manager.get_store_mut();
28///
29/// counter.count = 75;
30///
31/// // Save the data to the storage
32/// manager.save().expect("Failed to save count to storage");
33///
34/// let counter = manager.get_store();
35///
36/// println!("Count: {}", counter.count);
37/// ```
38#[derive(Debug, Clone)]
39pub struct StoreManager<T: Storing> {
40    store: Storage,
41    handle: StoreHandle<T>,
42}
43
44impl<T: Storing> StoreManager<T> {
45    /// Creates a new `StoreManager` by reading the store data from the provided `Storage` into the `StoreHandle`.
46    ///
47    /// This function attempts to read the store data from the storage.
48    ///
49    ///
50    /// # Example
51    ///
52    /// ```
53    /// use serde::{Deserialize, Serialize};
54    /// use rusty_store::{StoreManager, Storing, Storage, StoreHandle};
55    ///
56    /// #[derive(Serialize, Deserialize, Default, Storing)]
57    /// pub struct MyStore {
58    ///     pub count: u32,
59    /// }
60    ///
61    /// let storage = Storage::new("app_id");
62    /// let handle = StoreHandle::<MyStore>::new("my_store_id");
63    /// let manager = StoreManager::from_handle(&storage, handle).expect("Failed to create StoreManager");
64    /// ```
65    pub fn from_handle(storage: &Storage, mut handle: StoreHandle<T>) -> Result<Self, StoreError> {
66        storage.read(&mut handle)?;
67
68        Ok(Self {
69            store: storage.clone(),
70            handle,
71        })
72    }
73
74    /// Creates a new `StoreManager` by reading the store data from the provided `Storage` into the `StoreHandle`.
75    ///
76    /// This function attempts to read the store data from the storage.
77    ///
78    ///
79    /// # Example
80    ///
81    /// ```
82    /// use serde::{Deserialize, Serialize};
83    /// use rusty_store::{StoreManager, Storing, Storage};
84    ///
85    /// #[derive(Serialize, Deserialize, Default, Storing)]
86    /// pub struct MyStore {
87    ///     pub count: u32,
88    /// }
89    ///
90    /// let storage = Storage::new("APP_ID");
91    /// let manager = StoreManager::<MyStore>::new(&storage, "my_store_id").expect("Failed to create StoreManager");
92    /// ```
93    pub fn new(storage: &Storage, store_id: &str) -> Result<Self, StoreError> {
94        let mut handle = StoreHandle::<T>::new(store_id);
95        storage.read(&mut handle)?;
96
97        Ok(Self {
98            store: storage.clone(),
99            handle,
100        })
101    }
102
103    /// Returns a reference to the stored data.
104    pub fn get_store(&self) -> &T {
105        self.handle.get_store()
106    }
107
108    /// Returns a reference to the stored data.
109    pub fn get_store_mut(&mut self) -> &mut T {
110        self.handle.get_store_mut()
111    }
112
113    /// Reads the stored data from the storage.
114    /// This allows to get changes external to the application
115    pub fn get_store_alive(&mut self) -> Result<&T, StoreError> {
116        self.store.read(&mut self.handle)?;
117        Ok(self.handle.get_store())
118    }
119
120    /// Modifies the store and commits the changes to the storage
121    ///
122    /// # Example
123    ///
124    /// ```
125    /// use serde::{Deserialize, Serialize};
126    /// use rusty_store::{StoreManager, Storing, Storage};
127    ///
128    /// #[derive(Serialize, Deserialize, Default, Storing)]
129    /// pub struct MyStore {
130    ///     pub count: u32,
131    /// }
132    ///
133    /// let storage = Storage::new("APP_ID");
134    /// let mut manager = StoreManager::<MyStore>::new(&storage, "my_store_id")
135    ///        .expect("Failed to create StoreManager");
136    ///
137    /// manager.modify_store(|store| store.count = 25).expect("Failed to write store modifications");
138    /// ```
139    pub fn modify_store<F>(&mut self, mut change: F) -> Result<(), StoreError>
140    where
141        F: FnMut(&mut T),
142    {
143        let store = self.handle.get_store_mut();
144        change(store);
145        self.save()
146    }
147
148    /// This method is used to modify the store without committing changes to disk.
149    ///
150    /// # Example
151    ///
152    /// ```
153    /// use serde::{Deserialize, Serialize};
154    /// use rusty_store::{StoreManager, Storing, Storage};
155    ///
156    /// #[derive(Serialize, Deserialize, Default, Storing)]
157    /// pub struct MyStore {
158    ///     pub count: u32,
159    /// }
160    ///
161    /// let storage = Storage::new("APP_ID");
162    /// let mut manager = StoreManager::<MyStore>::new(&storage, "my_store_id")
163    ///        .expect("Failed to create StoreManager");
164    ///
165    /// manager.modify_store_uncommitted(|store| store.count = 25);
166    ///
167    /// manager.save().expect("Failed to save modifications");
168    /// ```
169    pub fn modify_store_uncommitted<F>(&mut self, mut change: F)
170    where
171        F: FnMut(&mut T),
172    {
173        let store = self.handle.get_store_mut();
174        change(store);
175    }
176
177    /// This method writes the current state of the store to the storage.
178    pub fn save(&mut self) -> Result<(), StoreError> {
179        self.store.write(&mut self.handle)
180    }
181}