cyfs_util/storage/
local_store.rs1use 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) => 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}