millipede_core/storage/
auto_saved.rs1use super::{KeyValueStore, KeyValueStoreExt, StorageResult};
4use serde::{Serialize, de::DeserializeOwned};
5use std::{fmt, sync::Arc};
6
7pub struct AutoSaved<T> {
12 store: Arc<dyn KeyValueStore>,
13 key: String,
14 value: tokio::sync::RwLock<T>,
15}
16
17impl<T> fmt::Debug for AutoSaved<T> {
18 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
19 formatter
20 .debug_struct("AutoSaved")
21 .field("key", &self.key)
22 .finish_non_exhaustive()
23 }
24}
25
26impl<T: Serialize + DeserializeOwned + Send + Sync + 'static> AutoSaved<T> {
27 pub async fn open(
29 store: Arc<dyn KeyValueStore>,
30 key: impl Into<String>,
31 default: T,
32 ) -> StorageResult<Self> {
33 let key = key.into();
34 let value = store.get(&key).await?.unwrap_or(default);
35 Ok(Self {
36 store,
37 key,
38 value: tokio::sync::RwLock::new(value),
39 })
40 }
41
42 pub async fn get(&self) -> T
44 where
45 T: Clone,
46 {
47 self.value.read().await.clone()
48 }
49
50 pub async fn set(&self, value: T) {
52 *self.value.write().await = value;
53 }
54
55 pub async fn update<F: FnOnce(&mut T) + Send>(&self, f: F) {
57 f(&mut *self.value.write().await);
58 }
59
60 pub async fn persist(&self) -> StorageResult<()> {
62 let bytes = serde_json::to_vec(&*self.value.read().await)?;
63 self.store
64 .set_bytes(&self.key, bytes.into(), "application/json")
65 .await
66 }
67}