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}