gloo_storage/
lib.rs

1//! This crate provides wrappers for the
2//! [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API)
3//!
4//! The data is stored in JSON form. We use [`serde`](https://serde.rs) for
5//! serialization and deserialization.
6
7#![deny(missing_docs, missing_debug_implementations)]
8
9use serde::{Deserialize, Serialize};
10use wasm_bindgen::prelude::*;
11
12use crate::errors::js_to_error;
13use errors::StorageError;
14use serde_json::{Map, Value};
15
16pub mod errors;
17mod local_storage;
18mod session_storage;
19pub use local_storage::LocalStorage;
20pub use session_storage::SessionStorage;
21
22/// `gloo-storage`'s `Result`
23pub type Result<T> = std::result::Result<T, StorageError>;
24
25/// Trait which provides implementations for managing storage in the browser.
26pub trait Storage {
27    /// Get the raw [`web_sys::Storage`] instance
28    fn raw() -> web_sys::Storage;
29
30    /// Get the value for the specified key
31    fn get<T>(key: impl AsRef<str>) -> Result<T>
32    where
33        T: for<'de> Deserialize<'de>,
34    {
35        let key = key.as_ref();
36        let item = Self::raw()
37            .get_item(key)
38            .expect_throw("unreachable: get_item does not throw an exception")
39            .ok_or_else(|| StorageError::KeyNotFound(key.to_string()))?;
40        let item = serde_json::from_str(&item)?;
41        Ok(item)
42    }
43
44    /// Get all the stored keys and their values
45    fn get_all<T>() -> Result<T>
46    where
47        T: for<'a> Deserialize<'a>,
48    {
49        let local_storage = Self::raw();
50        let length = Self::length();
51        let mut map = Map::with_capacity(length as usize);
52        for index in 0..length {
53            let key = local_storage
54                .key(index)
55                .map_err(js_to_error)?
56                .unwrap_throw();
57            let value: Value = Self::get(&key)?;
58            map.insert(key, value);
59        }
60        Ok(serde_json::from_value(Value::Object(map))?)
61    }
62
63    /// Insert a value for the specified key
64    fn set<T>(key: impl AsRef<str>, value: T) -> Result<()>
65    where
66        T: Serialize,
67    {
68        let key = key.as_ref();
69        let value = serde_json::to_string(&value)?;
70        Self::raw()
71            .set_item(key, &value)
72            .map_err(errors::js_to_error)?;
73        Ok(())
74    }
75
76    /// Remove a key and it's stored value
77    fn delete(key: impl AsRef<str>) {
78        let key = key.as_ref();
79        Self::raw()
80            .remove_item(key)
81            .expect_throw("unreachable: remove_item does not throw an exception");
82    }
83
84    /// Remove all the stored data
85    fn clear() {
86        Self::raw()
87            .clear()
88            .expect_throw("unreachable: clear does not throw an exception");
89    }
90
91    /// Get the number of items stored
92    fn length() -> u32 {
93        Self::raw()
94            .length()
95            .expect_throw("unreachable: length does not throw an exception")
96    }
97}