Skip to main content

iris_ztd/
zmap.rs

1use core::borrow::Borrow;
2
3use crate::zbase::{ZBase, ZEntry, ZHashableEntry};
4use crate::{Hashable, NounDecode, NounEncode};
5use alloc::fmt::Debug;
6#[cfg(feature = "wasm")]
7use alloc::{boxed::Box, format, string::ToString};
8
9#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hashable, NounDecode, NounEncode)]
10#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
11#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi, type = "[K, V]"))]
12pub struct ZMapEntry<K, V> {
13    key: K,
14    value: V,
15}
16
17impl<K: Hashable + NounEncode, V: NounEncode> ZEntry for ZMapEntry<K, V> {
18    type Key = K;
19    type Value = V;
20    type Pair = (K, V);
21    type BorrowPair<'a>
22        = (&'a K, &'a V)
23    where
24        K: 'a,
25        V: 'a;
26
27    fn key(&self) -> &Self::Key {
28        &self.key
29    }
30
31    fn value(&self) -> &Self::Value {
32        &self.value
33    }
34
35    fn value_mut(&mut self) -> &mut Self::Value {
36        &mut self.value
37    }
38
39    fn pair(&self) -> Self::BorrowPair<'_> {
40        (&self.key, &self.value)
41    }
42
43    fn into_key(self) -> Self::Key {
44        self.key
45    }
46
47    fn into_value(self) -> Self::Value {
48        self.value
49    }
50
51    fn into_pair(self) -> Self::Pair {
52        (self.key, self.value)
53    }
54
55    fn from_pair((key, value): Self::Pair) -> Self {
56        Self { key, value }
57    }
58}
59
60impl<K: Hashable + NounEncode, V: Hashable + NounEncode> ZHashableEntry for ZMapEntry<K, V> {
61    type HashableBorrowPair<'a>
62        = (&'a K, &'a V)
63    where
64        K: 'a,
65        V: 'a;
66
67    fn hashable_pair(&self) -> Self::HashableBorrowPair<'_> {
68        (&self.key, &self.value)
69    }
70}
71
72#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, NounDecode, NounEncode, Hashable)]
73#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
74#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
75pub struct ZMap<K, V>(pub ZBase<ZMapEntry<K, V>>);
76
77// Unfortunately, we need to reimplement this, because type/lifetime limitations.
78impl<K, V> serde::Serialize for ZMap<K, V>
79where
80    K: Hashable + NounEncode + serde::Serialize,
81    V: NounEncode + serde::Serialize,
82{
83    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
84    where
85        S: serde::Serializer,
86    {
87        use serde::ser::SerializeSeq;
88        let mut seq = serializer.serialize_seq(None)?;
89        for entry in self.0.iter() {
90            seq.serialize_element(&entry)?;
91        }
92        seq.end()
93    }
94}
95
96impl<'de, K, V> serde::Deserialize<'de> for ZMap<K, V>
97where
98    K: Hashable + NounEncode + serde::Deserialize<'de>,
99    V: NounEncode + serde::Deserialize<'de>,
100{
101    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
102    where
103        D: serde::Deserializer<'de>,
104    {
105        Ok(Self(ZBase::deserialize(deserializer)?))
106    }
107}
108
109impl<K, V> Default for ZMap<K, V>
110where
111    K: Hashable + NounEncode,
112    V: NounEncode,
113{
114    fn default() -> Self {
115        Self(ZBase::default())
116    }
117}
118
119impl<K, V> core::ops::Deref for ZMap<K, V> {
120    type Target = ZBase<ZMapEntry<K, V>>;
121
122    fn deref(&self) -> &Self::Target {
123        &self.0
124    }
125}
126
127impl<K, V> core::ops::DerefMut for ZMap<K, V> {
128    fn deref_mut(&mut self) -> &mut Self::Target {
129        &mut self.0
130    }
131}
132
133impl<K, V> IntoIterator for ZMap<K, V>
134where
135    K: Hashable + NounEncode,
136    V: NounEncode,
137{
138    type Item = (K, V);
139    type IntoIter = crate::zbase::ZBaseIntoIterator<ZMapEntry<K, V>>;
140
141    fn into_iter(self) -> Self::IntoIter {
142        self.0.into_iter()
143    }
144}
145
146impl<K, V> FromIterator<(K, V)> for ZMap<K, V>
147where
148    K: Hashable + NounEncode,
149    V: NounEncode,
150{
151    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
152        Self(ZBase::from_iter(iter))
153    }
154}
155
156impl<K, V> From<ZMap<K, V>> for alloc::vec::Vec<(K, V)>
157where
158    K: Hashable + NounEncode,
159    V: NounEncode,
160{
161    fn from(map: ZMap<K, V>) -> Self {
162        map.into_iter().collect()
163    }
164}
165
166impl<'a, K, V> IntoIterator for &'a ZMap<K, V>
167where
168    K: Hashable + NounEncode,
169    V: NounEncode,
170{
171    type Item = (&'a K, &'a V);
172    type IntoIter = crate::zbase::ZBaseIterator<'a, ZMapEntry<K, V>>;
173
174    fn into_iter(self) -> Self::IntoIter {
175        self.0.iter()
176    }
177}
178
179impl<K, V> From<alloc::vec::Vec<(K, V)>> for ZMap<K, V>
180where
181    K: Hashable + NounEncode,
182    V: NounEncode,
183{
184    fn from(v: alloc::vec::Vec<(K, V)>) -> Self {
185        Self(crate::zbase::ZBase::from(v))
186    }
187}
188
189impl<K, V, const N: usize> From<[(K, V); N]> for ZMap<K, V>
190where
191    K: Hashable + NounEncode,
192    V: NounEncode,
193{
194    fn from(v: [(K, V); N]) -> Self {
195        Self(crate::zbase::ZBase::from(v))
196    }
197}
198
199impl<K: Hashable + NounEncode, V: NounEncode> ZMap<K, V> {
200    pub fn new() -> Self {
201        Self::default()
202    }
203
204    pub fn insert(&mut self, key: K, value: V) {
205        self.0.insert_entry(ZMapEntry { key, value });
206    }
207
208    pub fn get_key_value<Q: NounEncode + ?Sized>(&self, key: &Q) -> Option<(&K, &V)>
209    where
210        K: Borrow<Q>,
211    {
212        self.0.get_entry(key).map(|e| e.pair())
213    }
214}
215
216#[cfg(test)]
217mod tests {
218    use super::*;
219    use alloc::string::{String, ToString};
220    use alloc::vec::Vec;
221
222    #[test]
223    fn test_zmap_encode_decode() {
224        let mut zm = ZMap::<String, u64>::new();
225        zm.insert("ver".to_string(), 10);
226        zm.insert("ve2".to_string(), 11);
227        let zm_noun = zm.to_noun();
228        let zm_decode = ZMap::<String, u64>::from_noun(&zm_noun).unwrap();
229        assert_eq!(Vec::from(zm), Vec::from(zm_decode));
230    }
231
232    #[test]
233    fn test_zmap_serde() {
234        let mut zm = ZMap::<String, (u64, u64)>::new();
235        zm.insert("ver".to_string(), (10, 12));
236        zm.insert("ve2".to_string(), (11, 13));
237        let json = serde_json::to_string(&zm).unwrap();
238        let zm2: ZMap<String, (u64, u64)> = serde_json::from_str(&json).unwrap();
239        assert_eq!(zm, zm2);
240    }
241}