tauri_store/store/
state.rs

1use crate::error::Result;
2use crate::io_err;
3use serde::de::DeserializeOwned;
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5use serde_json::{Map, Value};
6use std::collections::HashMap;
7use std::result::Result as StdResult;
8
9/// Internal state of a store.
10#[derive(Clone, Debug, Default)]
11pub struct StoreState(HashMap<String, Value>);
12
13impl StoreState {
14  /// Creates an empty [`StoreState`].
15  pub fn new() -> Self {
16    Self::default()
17  }
18
19  /// Creates an empty [`StoreState`] with at least the specified capacity.
20  pub fn with_capacity(capacity: usize) -> Self {
21    Self(HashMap::with_capacity(capacity))
22  }
23
24  /// Consumes the [`StoreState`] and returns the inner [`HashMap`](std::collections::HashMap).
25  #[inline]
26  pub fn into_inner(self) -> HashMap<String, Value> {
27    self.0
28  }
29
30  /// Gets a reference to the raw value corresponding to the key.
31  pub fn get_raw(&self, key: impl AsRef<str>) -> Option<&Value> {
32    self.0.get(key.as_ref())
33  }
34
35  /// Gets a mutable reference to the raw value corresponding to the key.
36  pub fn get_raw_mut(&mut self, key: impl AsRef<str>) -> Option<&mut Value> {
37    self.0.get_mut(key.as_ref())
38  }
39
40  /// Gets a reference to the raw value corresponding to the key.
41  ///
42  /// # Safety
43  ///
44  /// This is *undefined behavior* if the key doesn't exist in the store.
45  pub unsafe fn get_raw_unchecked(&self, key: impl AsRef<str>) -> &Value {
46    unsafe { self.0.get(key.as_ref()).unwrap_unchecked() }
47  }
48
49  /// Gets a mutable reference to the raw value corresponding to the key.
50  ///
51  /// # Safety
52  ///
53  /// This is *undefined behavior* if the key doesn't exist in the store.
54  pub unsafe fn get_raw_unchecked_mut(&mut self, key: impl AsRef<str>) -> &mut Value {
55    unsafe { self.0.get_mut(key.as_ref()).unwrap_unchecked() }
56  }
57
58  /// Gets a value and tries to parse it as an instance of type `T`.
59  pub fn get<T>(&self, key: impl AsRef<str>) -> Result<T>
60  where
61    T: DeserializeOwned,
62  {
63    let key = key.as_ref();
64    let Some(value) = self.0.get(key).cloned() else {
65      return io_err!(NotFound, "key not found: {key}");
66    };
67
68    Ok(serde_json::from_value(value)?)
69  }
70
71  /// Gets a value and tries to parse it as an instance of type `T`.
72  ///
73  /// If it does not exist, returns the provided default value.
74  pub fn get_or<T>(&self, key: impl AsRef<str>, default: T) -> T
75  where
76    T: DeserializeOwned,
77  {
78    self.get(key).unwrap_or(default)
79  }
80
81  /// Gets a value and tries to parse it as an instance of type `T`.
82  ///
83  /// If it does not exist, returns the default value of `T`.
84  pub fn get_or_default<T>(&self, key: impl AsRef<str>) -> T
85  where
86    T: DeserializeOwned + Default,
87  {
88    self.get(key).unwrap_or_default()
89  }
90
91  /// Gets a value and tries to parse it as an instance of type `T`.
92  ///
93  /// If it does not exist, returns the result of the provided closure.
94  pub fn get_or_else<T>(&self, key: impl AsRef<str>, f: impl FnOnce() -> T) -> T
95  where
96    T: DeserializeOwned,
97  {
98    self.get(key).unwrap_or_else(|_| f())
99  }
100
101  /// Gets a value and parses it as an instance of type `T`.
102  ///
103  /// # Safety
104  ///
105  /// This is *undefined behavior* if the key doesn't exist in the store
106  /// **OR** if the value cannot be represented as a valid `T`.
107  pub unsafe fn get_unchecked<T>(&self, key: impl AsRef<str>) -> T
108  where
109    T: DeserializeOwned,
110  {
111    self.get(key).unwrap_unchecked()
112  }
113
114  /// Sets a key-value pair, returning the previous value, if any.
115  pub fn set(&mut self, key: impl AsRef<str>, value: impl Into<Value>) -> Option<Value> {
116    let key = key.as_ref().to_owned();
117    self.0.insert(key, value.into())
118  }
119
120  /// Patches the state.
121  pub fn patch(&mut self, state: impl Into<StoreState>) {
122    self.0.extend(state.into().0);
123  }
124
125  /// Whether a key exists.
126  pub fn has(&self, key: impl AsRef<str>) -> bool {
127    self.0.contains_key(key.as_ref())
128  }
129
130  /// Creates an iterator over the keys.
131  pub fn keys(&self) -> impl Iterator<Item = &String> {
132    self.0.keys()
133  }
134
135  /// Creates an iterator over the values.
136  pub fn values(&self) -> impl Iterator<Item = &Value> {
137    self.0.values()
138  }
139
140  /// Creates an iterator over mutable references to the values.
141  pub fn values_mut(&mut self) -> impl Iterator<Item = &mut Value> {
142    self.0.values_mut()
143  }
144
145  /// Creates an iterator over the entries.
146  pub fn entries(&self) -> impl Iterator<Item = (&String, &Value)> {
147    self.0.iter()
148  }
149
150  /// Creates an iterator over mutable references to the entries.
151  pub fn entries_mut(&mut self) -> impl Iterator<Item = (&String, &mut Value)> {
152    self.0.iter_mut()
153  }
154
155  /// Removes a key, returning the previous value, if any.
156  pub fn remove(&mut self, key: impl AsRef<str>) -> Option<Value> {
157    self.0.remove(key.as_ref())
158  }
159
160  /// Retains only the values specified by the predicate.
161  pub fn retain<F>(&mut self, f: F)
162  where
163    F: FnMut(&String, &mut Value) -> bool,
164  {
165    self.0.retain(f);
166  }
167
168  /// Clears the store state, removing all key-value pairs.
169  #[inline]
170  pub fn clear(&mut self) {
171    self.0.clear();
172  }
173
174  /// Returns the amount of items.
175  #[inline]
176  pub fn len(&self) -> usize {
177    self.0.len()
178  }
179
180  /// Whether it is empty.
181  #[inline]
182  pub fn is_empty(&self) -> bool {
183    self.0.is_empty()
184  }
185}
186
187impl Serialize for StoreState {
188  fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
189  where
190    S: Serializer,
191  {
192    self.0.serialize(serializer)
193  }
194}
195
196impl<'de> Deserialize<'de> for StoreState {
197  fn deserialize<D>(deserializer: D) -> StdResult<Self, D::Error>
198  where
199    D: Deserializer<'de>,
200  {
201    type Map = HashMap<String, Value>;
202    Ok(Self(Map::deserialize(deserializer)?))
203  }
204}
205
206impl From<HashMap<String, Value>> for StoreState {
207  fn from(map: HashMap<String, Value>) -> Self {
208    Self(map)
209  }
210}
211
212impl<K, V> FromIterator<(K, V)> for StoreState
213where
214  K: Into<String>,
215  V: Into<Value>,
216{
217  fn from_iter<I>(iter: I) -> Self
218  where
219    I: IntoIterator<Item = (K, V)>,
220  {
221    let state = iter
222      .into_iter()
223      .map(|(k, v)| (k.into(), v.into()))
224      .collect();
225
226    Self(state)
227  }
228}
229
230impl<K, V> From<(K, V)> for StoreState
231where
232  K: Into<String>,
233  V: Into<Value>,
234{
235  fn from((key, value): (K, V)) -> Self {
236    Self::from_iter([(key, value)])
237  }
238}
239
240impl<K, V> From<Vec<(K, V)>> for StoreState
241where
242  K: Into<String>,
243  V: Into<Value>,
244{
245  fn from(pairs: Vec<(K, V)>) -> Self {
246    Self::from_iter(pairs)
247  }
248}
249
250impl<const N: usize, K, V> From<[(K, V); N]> for StoreState
251where
252  K: Into<String>,
253  V: Into<Value>,
254{
255  fn from(pairs: [(K, V); N]) -> Self {
256    Self::from_iter(pairs)
257  }
258}
259
260impl From<StoreState> for Value {
261  fn from(state: StoreState) -> Self {
262    Value::from(Map::from_iter(state.0))
263  }
264}
265
266impl From<&StoreState> for Value {
267  fn from(state: &StoreState) -> Self {
268    Value::from(state.clone())
269  }
270}