Skip to content

Commit fd17c28

Browse files
mgoldenbergHywan
authored andcommitted
refactor(indexeddb): add convenience functions for (de)serializing Indexed types
Signed-off-by: Michael Goldenberg <m@mgoldenberg.net>
1 parent 841131f commit fd17c28

File tree

1 file changed

+141
-0
lines changed
  • crates/matrix-sdk-indexeddb/src/event_cache_store/serializer

1 file changed

+141
-0
lines changed

crates/matrix-sdk-indexeddb/src/event_cache_store/serializer/mod.rs

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,146 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License
1414

15+
use gloo_utils::format::JsValueSerdeExt;
16+
use matrix_sdk_crypto::CryptoStoreError;
17+
use ruma::RoomId;
18+
use serde::{de::DeserializeOwned, Serialize};
19+
use thiserror::Error;
20+
use wasm_bindgen::JsValue;
21+
use web_sys::IdbKeyRange;
22+
23+
use crate::{
24+
event_cache_store::serializer::traits::{Indexed, IndexedKey, IndexedKeyBounds},
25+
serializer::IndexeddbSerializer,
26+
};
27+
1528
mod traits;
1629
mod types;
30+
31+
#[derive(Debug, Error)]
32+
pub enum IndexeddbEventCacheStoreSerializerError {
33+
#[error("indexing: {0}")]
34+
Indexing(Box<dyn std::error::Error>),
35+
#[error("serialization: {0}")]
36+
Serialization(#[from] serde_json::Error),
37+
}
38+
39+
impl From<serde_wasm_bindgen::Error> for IndexeddbEventCacheStoreSerializerError {
40+
fn from(e: serde_wasm_bindgen::Error) -> Self {
41+
Self::Serialization(serde::de::Error::custom(e.to_string()))
42+
}
43+
}
44+
45+
/// A (de)serializer for an IndexedDB implementation of [`EventCacheStore`][1].
46+
///
47+
/// This is primarily a wrapper around [`IndexeddbSerializer`] with a
48+
/// convenience functions for (de)serializing types specific to the
49+
/// [`EventCacheStore`][1].
50+
///
51+
/// [1]: matrix_sdk_base::event_cache::store::EventCacheStore
52+
pub struct IndexeddbEventCacheStoreSerializer {
53+
inner: IndexeddbSerializer,
54+
}
55+
56+
impl IndexeddbEventCacheStoreSerializer {
57+
pub fn new(inner: IndexeddbSerializer) -> Self {
58+
Self { inner }
59+
}
60+
61+
/// Encodes an key for a [`Indexed`] type.
62+
///
63+
/// Note that the particular key which is encoded is defined by the type
64+
/// `K`.
65+
pub fn encode_key<T, K>(&self, room_id: &RoomId, components: &K::KeyComponents) -> K
66+
where
67+
T: Indexed,
68+
K: IndexedKey<T>,
69+
{
70+
K::encode(room_id, components, &self.inner)
71+
}
72+
73+
/// Encodes a key for a [`Indexed`] type as a [`JsValue`].
74+
///
75+
/// Note that the particular key which is encoded is defined by the type
76+
/// `K`.
77+
pub fn encode_key_as_value<T, K>(
78+
&self,
79+
room_id: &RoomId,
80+
components: &K::KeyComponents,
81+
) -> Result<JsValue, serde_wasm_bindgen::Error>
82+
where
83+
T: Indexed,
84+
K: IndexedKey<T> + Serialize,
85+
{
86+
serde_wasm_bindgen::to_value(&self.encode_key::<T, K>(room_id, components))
87+
}
88+
89+
/// Encodes the entire key range for an [`Indexed`] type.
90+
///
91+
/// Note that the particular key which is encoded is defined by the type
92+
/// `K`.
93+
pub fn encode_key_range<T, K>(
94+
&self,
95+
room_id: &RoomId,
96+
) -> Result<IdbKeyRange, serde_wasm_bindgen::Error>
97+
where
98+
T: Indexed,
99+
K: IndexedKeyBounds<T> + Serialize,
100+
{
101+
let lower = serde_wasm_bindgen::to_value(&K::encode_lower(room_id, &self.inner))?;
102+
let upper = serde_wasm_bindgen::to_value(&K::encode_upper(room_id, &self.inner))?;
103+
IdbKeyRange::bound(&lower, &upper).map_err(Into::into)
104+
}
105+
106+
/// Encodes a bounded key range for an [`Indexed`] type from `lower` to
107+
/// `upper`.
108+
///
109+
/// Note that the particular key which is encoded is defined by the type
110+
/// `K`.
111+
pub fn encode_key_range_from_to<T, K>(
112+
&self,
113+
room_id: &RoomId,
114+
lower: &K::KeyComponents,
115+
upper: &K::KeyComponents,
116+
) -> Result<IdbKeyRange, serde_wasm_bindgen::Error>
117+
where
118+
T: Indexed,
119+
K: IndexedKeyBounds<T> + Serialize,
120+
{
121+
let lower = serde_wasm_bindgen::to_value(&K::encode(room_id, lower, &self.inner))?;
122+
let upper = serde_wasm_bindgen::to_value(&K::encode(room_id, upper, &self.inner))?;
123+
IdbKeyRange::bound(&lower, &upper).map_err(Into::into)
124+
}
125+
126+
/// Serializes an [`Indexed`] type into a [`JsValue`]
127+
pub fn serialize<T>(
128+
&self,
129+
room_id: &RoomId,
130+
t: &T,
131+
) -> Result<JsValue, IndexeddbEventCacheStoreSerializerError>
132+
where
133+
T: Indexed,
134+
T::IndexedType: Serialize,
135+
T::Error: std::error::Error + 'static,
136+
{
137+
let indexed = t
138+
.to_indexed(room_id, &self.inner)
139+
.map_err(|e| IndexeddbEventCacheStoreSerializerError::Indexing(Box::new(e)))?;
140+
serde_wasm_bindgen::to_value(&indexed).map_err(Into::into)
141+
}
142+
143+
/// Deserializes an [`Indexed`] type from a [`JsValue`]
144+
pub fn deserialize<T>(
145+
&self,
146+
value: JsValue,
147+
) -> Result<T, IndexeddbEventCacheStoreSerializerError>
148+
where
149+
T: Indexed,
150+
T::IndexedType: DeserializeOwned,
151+
T::Error: std::error::Error + 'static,
152+
{
153+
let indexed: T::IndexedType = value.into_serde()?;
154+
T::from_indexed(indexed, &self.inner)
155+
.map_err(|e| IndexeddbEventCacheStoreSerializerError::Indexing(Box::new(e)))
156+
}
157+
}

0 commit comments

Comments
 (0)