cyfs_util/storage/
local_store.rs

1use super::AsyncStorageSync;
2use cyfs_base::BuckyError;
3use serde::Serialize;
4
5pub struct LocalStore {
6    prefix: Option<String>,
7    async_storage: AsyncStorageSync,
8}
9
10impl LocalStore {
11    pub fn new(prefix: Option<&str>, async_storage: AsyncStorageSync) -> Self {
12        Self {
13            prefix: prefix.map(|v| v.to_owned()),
14            async_storage,
15        }
16    }
17
18    pub fn sub_store(&self, sub_key: &str) -> LocalStore {
19        assert!(sub_key.len() > 0);
20
21        let sub_key = match self.prefix.as_ref() {
22            Some(v) => format!("{}_{}", v, sub_key),
23            None => sub_key.to_owned(),
24        };
25
26        Self::new(Some(&sub_key), self.async_storage.clone())
27    }
28
29    fn _key(&self, key: &str) -> String {
30        match self.prefix.as_ref() {
31            Some(v) => format!("{}_{}", v, key),
32            None => key.to_owned(),
33        }
34    }
35
36    pub async fn set(&mut self, key: &str, value: String) -> Result<(), BuckyError> {
37        let key = self._key(key);
38
39        let mut async_storage = self.async_storage.lock().await;
40        async_storage.set_item(&key, value).await
41    }
42
43    pub async fn set_obj<T>(&mut self, key: &str, value: &T) -> Result<(), BuckyError>
44    where
45        T: ?Sized + Serialize,
46    {
47        let value = serde_json::to_string(value).unwrap();
48        self.set(key, value).await
49    }
50
51    pub async fn get(&mut self, key: &str) -> Option<String> {
52        let key = self._key(key);
53
54        let async_storage = self.async_storage.lock().await;
55        async_storage.get_item(&key).await
56    }
57
58    pub async fn get_obj<T>(&mut self, key: &str) -> Result<Option<T>, BuckyError>
59    where
60        T: serde::de::DeserializeOwned,
61    {
62        match self.get(key).await {
63            Some(v) => match serde_json::from_str(&v) {
64                Ok(obj) => Ok(Some(obj)),
65                Err(e) => {
66                    let msg = format!(
67                        "unserialize obj from string error! err={}, content={}",
68                        e, v
69                    );
70                    error!("{}", msg);
71
72                    Err(BuckyError::from(msg))
73                }
74            },
75            None => Ok(None),
76        }
77    }
78
79    pub async fn remove(&mut self, key: &str) -> Option<()> {
80        let key = self._key(key);
81
82        let mut async_storage = self.async_storage.lock().await;
83        async_storage.remove_item(&key).await
84    }
85
86    pub async fn remove_obj<T>(&mut self, key: &str) -> Result<Option<()>, BuckyError>
87    where
88        T: serde::de::DeserializeOwned,
89    {
90        match self.remove(key).await {
91            // Some(v) => match serde_json::from_str(&v) {
92            //     Ok(obj) => Ok(Some(obj)),
93            //     Err(e) => {
94            //         let msg = format!(
95            //             "unserialize obj from string error! err={}, content={}",
96            //             e, v
97            //         );
98            //         error!("{}", msg);
99
100            //         Err(BuckyError::from(msg))
101            //     }
102            // },
103            Some(_v) => Ok(Some(())),
104            None => Ok(None),
105        }
106    }
107
108    pub async fn clear(&mut self) {
109        match self.prefix.as_ref() {
110            Some(value) => {
111                let prefix = format!("{}_", value);
112                let mut async_storage = self.async_storage.lock().await;
113                async_storage.clear_with_prefix(&prefix).await;
114            }
115            None => {
116                let mut async_storage = self.async_storage.lock().await;
117                async_storage.clear().await;
118            }
119        }
120    }
121}
122
123#[cfg(test)]
124mod tests {
125
126    use super::super::{into_async_storage_sync, FileStorage, SqliteStorage};
127    use super::LocalStore;
128    use serde::{Deserialize, Serialize};
129    extern crate simple_logger;
130    #[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
131    struct TestObj {
132        name: String,
133        value: i32,
134    }
135
136    #[async_std::test]
137    async fn test_file_store() {
138        let mut file_storage = FileStorage::new();
139        file_storage.init("test").await.unwrap();
140
141        let mut store = LocalStore::new(None, into_async_storage_sync(file_storage));
142        store.set("name", "xxx".to_owned()).await.unwrap();
143
144        assert_eq!(store.get("name").await.unwrap(), "xxx");
145
146        let mut store = store.sub_store("app");
147        store.set("name", "xxx".to_owned()).await.unwrap();
148
149        assert_eq!(store.get("name").await.unwrap(), "xxx");
150
151        let test_obj = TestObj {
152            name: "jack".to_owned(),
153            value: -1,
154        };
155
156        store.set_obj("obj", &test_obj).await.unwrap();
157
158        assert_eq!(
159            store.get_obj::<TestObj>("obj").await.unwrap().unwrap(),
160            test_obj
161        );
162
163        assert_eq!(
164            store.remove_obj::<TestObj>("obj").await.unwrap().unwrap(),
165            ()
166        );
167        assert_eq!(store.remove_obj::<TestObj>("obj").await.unwrap(), None);
168
169        store.clear().await;
170
171        assert!(store.get("obj").await == None);
172        assert!(store.get_obj::<TestObj>("obj").await.unwrap() == None);
173
174        store.set_obj("obj", &test_obj).await.unwrap();
175    }
176
177    #[async_std::test]
178    async fn test_sqlite_store() {
179        let mut sqlite_storage = SqliteStorage::new();
180        sqlite_storage.init("test").await.unwrap();
181
182        let mut store = LocalStore::new(None, into_async_storage_sync(sqlite_storage));
183        store.set("name", "xxx".to_owned()).await.unwrap();
184
185        assert_eq!(store.get("name").await.unwrap(), "xxx");
186
187        let mut store = store.sub_store("app");
188        store.set("name", "xxx".to_owned()).await.unwrap();
189
190        assert_eq!(store.get("name").await.unwrap(), "xxx");
191
192        let test_obj = TestObj {
193            name: "jack".to_owned(),
194            value: -1,
195        };
196
197        store.set_obj("obj", &test_obj).await.unwrap();
198
199        assert_eq!(store.remove_obj::<TestObj>("obj").await.unwrap(), Some(()));
200        assert_eq!(store.remove_obj::<TestObj>("obj").await.unwrap(), None);
201
202        store.clear().await;
203
204        assert!(store.get("obj").await == None);
205        assert!(store.get_obj::<TestObj>("obj").await.unwrap() == None);
206
207        store.set_obj("obj", &test_obj).await.unwrap();
208    }
209}