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
77impl<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}