1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
use crate::storage::{Storage, StoreError, StoreHandle, Storing};
/// Used to manage store handles
///
/// # Example
///
///```
/// use serde::{Deserialize, Serialize};
/// use storage::{manager::StorageManager, Storage, StoreHandle, Storing, StoringType};
///
/// #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
/// pub struct MyStore {
/// pub count: u32,
/// }
///
/// impl Storing for MyStore {
/// fn store_type() -> StoringType {
/// StoringType::Data
/// }
/// }
///
/// // Initialize the Storage with the defaults
/// let storage = Storage::new("com.github.mazynoah.storage".to_owned());
///
/// // Create a handle for managing the store data.
/// let handle = StoreHandle::<MyStore>::new("manager");
///
/// // Use `StorageManager` to manage the handle's change.
/// let mut manager =
/// StorageManager::new(&storage, handle).expect("Failed to create StorageManager");
///
/// // Get a mutable reference to the store
/// let counter = manager.get_store_mut();
///
/// counter.count = 75;
///
/// // Save the data to the storage
/// manager.save().expect("Failed to save count to storage");
///
/// let counter = manager.get_store();
///
/// println!("Count: {}", counter.count);
///
///```
#[derive(Debug, Clone)]
pub struct StorageManager<T: Storing> {
store: Storage,
handle: StoreHandle<T>,
}
impl<T: Storing> StorageManager<T> {
/// Creates a new `StorageManager` by reading the store data from the provided `Storage` into the `StoreHandle`.
///
/// This function attempts to read the store data from the storage.
///
///
/// # Example
///
/// ```
/// let storage = Storage::new(&app);
/// let handle = StoreHandle::<MyStore>::new("my_store_id");
/// let manager = StorageManager::new(&storage, handle).expect("Failed to create StorageManager");
/// ```
pub fn new(storage: &Storage, mut handle: StoreHandle<T>) -> Result<Self, StoreError> {
storage.read(&mut handle)?;
Ok(Self {
store: storage.clone(),
handle,
})
}
/// Returns a reference to the stored data.
pub fn get_store(&self) -> &T {
self.handle.get_store()
}
/// Returns a reference to the stored data.
pub fn get_store_mut(&mut self) -> &mut T {
self.handle.get_store_mut()
}
/// Reads the stored data from the storage.
/// This allows to get changes external to the application
pub fn get_store_alive(&mut self) -> Result<&T, StoreError> {
self.store.read(&mut self.handle)?;
Ok(self.handle.get_store())
}
/// This method is used to modify the store.
///
/// # Example
///
/// ```
/// let storage = Storage::new(&app);
/// let handle = StoreHandle::<MyStore>::new("my_store_id");
/// let manager = StorageManager::new(&storage, handle).expect("Failed to create StorageManager");
///
/// manager.modify_store(|store| store.some_field = 25).expect("Failed to write store modifications");
/// ```
pub fn modify_store<F>(&mut self, mut change: F) -> Result<(), StoreError>
where
F: FnMut(&mut T),
{
let store = self.handle.get_store_mut();
change(store);
self.save()
}
/// This method is used to modify the store without committing changes to disk.
///
/// # Example
///
/// ```
/// let storage = Storage::new(&app);
/// let handle = StoreHandle::<MyStore>::new("my_store_id");
/// let manager = StorageManager::new(&storage, handle).expect("Failed to create StorageManager");
///
/// manager.modify_store_uncommitted(|store| store.some_field = 25);
///
/// manager.save().expect("Failed to save modifications");
/// ```
pub fn modify_store_uncommitted<F>(&mut self, mut change: F)
where
F: FnMut(&mut T),
{
let store = self.handle.get_store_mut();
change(store);
}
/// This method writes the current state of the store to the storage.
pub fn save(&mut self) -> Result<(), StoreError> {
self.store.write(&mut self.handle)
}
}