leptos_form_core/
cache.rs1use ::core::future::Future;
2
3#[cfg(feature = "serde")]
4use ::serde::{de::DeserializeOwned, Serialize};
5
6pub trait Cache<CS: CacheSerializer<T>, T> {
7 type Error: Send;
8 fn get_item(&self, key: &str) -> impl Future<Output = Result<Option<T>, Self::Error>> + Send;
9 fn remove_item(&self, key: &str) -> impl Future<Output = Result<(), Self::Error>> + Send;
10 fn set_item(&self, key: &str, value: &T) -> impl Future<Output = Result<(), Self::Error>> + Send;
11}
12
13pub trait CacheSerializer<T> {
14 type Serialized;
15 type Error: Send;
16 fn serialize(value: &T) -> Result<Self::Serialized, Self::Error>;
17 fn deserialize(serialized: &Self::Serialized) -> Result<T, Self::Error>;
18}
19
20#[cfg(feature = "cache-local-storage")]
21pub struct LocalStorage<T>(pub T);
22
23#[cfg(feature = "cache-serde_json")]
24pub struct SerdeJson;
25
26#[cfg(feature = "serde")]
27pub trait SerdeSerializer {
28 type Serialized;
29 type Error: Send;
30 fn ser<T: Serialize>(value: &T) -> Result<Self::Serialized, Self::Error>;
31 fn de<T: DeserializeOwned>(value: &Self::Serialized) -> Result<T, Self::Error>;
32}
33
34#[cfg(feature = "serde")]
35impl<S: SerdeSerializer, T: DeserializeOwned + Serialize> CacheSerializer<T> for S {
36 type Serialized = S::Serialized;
37 type Error = S::Error;
38 fn serialize(value: &T) -> Result<Self::Serialized, Self::Error> {
39 S::ser(value)
40 }
41 fn deserialize(serialized: &Self::Serialized) -> Result<T, Self::Error> {
42 S::de(serialized)
43 }
44}
45
46#[cfg(feature = "cache-serde_json")]
47impl SerdeSerializer for SerdeJson {
48 type Serialized = String;
49 type Error = serde_json::Error;
50 fn ser<T: Serialize>(value: &T) -> Result<Self::Serialized, Self::Error> {
51 serde_json::to_string(value)
52 }
53 fn de<T: DeserializeOwned>(serialized: &Self::Serialized) -> Result<T, Self::Error> {
54 serde_json::from_str(serialized)
55 }
56}
57
58#[cfg(feature = "cache-local-storage")]
59impl<CS: CacheSerializer<T, Serialized = String>, T> Cache<CS, T> for LocalStorage<CS> {
60 type Error = CS::Error;
61 fn get_item(&self, key: &str) -> impl Future<Output = Result<Option<T>, CS::Error>> + Send {
62 use wasm_bindgen::UnwrapThrowExt;
63 let window = web_sys::window().unwrap_throw();
64 let local_storage = window.local_storage().unwrap_throw().unwrap_throw();
65 let serialized = local_storage.get_item(key).unwrap_throw();
66 async move {
67 let serialized = match serialized {
68 Some(serialized) => serialized,
69 None => return Ok(None),
70 };
71 CS::deserialize(&serialized).map(Some)
72 }
73 }
74 fn remove_item(&self, key: &str) -> impl Future<Output = Result<(), CS::Error>> + Send {
75 use wasm_bindgen::UnwrapThrowExt;
76 let window = web_sys::window().unwrap_throw();
77 let local_storage = window.local_storage().unwrap_throw().unwrap_throw();
78 local_storage.remove_item(key).unwrap_throw();
79 async move { Ok(()) }
80 }
81 fn set_item(&self, key: &str, value: &T) -> impl Future<Output = Result<(), CS::Error>> + Send {
82 use wasm_bindgen::UnwrapThrowExt;
83 let window = web_sys::window().unwrap_throw();
84 let local_storage = window.local_storage().unwrap_throw().unwrap_throw();
85 let res = CS::serialize(value).map(|serialized| local_storage.set_item(key, &serialized).unwrap_throw());
86 async move { res }
87 }
88}