1use super::{MutableZeroVecLike, ZeroMap, ZeroMapBorrowed, ZeroMapKV, ZeroVecLike};
6use core::fmt;
7use core::marker::PhantomData;
8use serde::de::{self, Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
9#[cfg(feature = "serde")]
10use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer};
11
12#[cfg(feature = "serde")]
14impl<'a, K, V> Serialize for ZeroMap<'a, K, V>
15where
16 K: ZeroMapKV<'a> + Serialize + ?Sized + Ord,
17 V: ZeroMapKV<'a> + Serialize + ?Sized,
18 K::Container: Serialize,
19 V::Container: Serialize,
20{
21 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
22 where
23 S: Serializer,
24 {
25 if serializer.is_human_readable() {
26 if let Some(k) = self.iter_keys().next() {
30 if !K::Container::zvl_get_as_t(k, super::serde_helpers::is_num_or_string) {
31 let mut seq = serializer.serialize_seq(Some(self.len()))?;
32 for (k, v) in self.iter() {
33 K::Container::zvl_get_as_t(k, |k| {
34 V::Container::zvl_get_as_t(v, |v| seq.serialize_element(&(k, v)))
35 })?;
36 }
37 return seq.end();
38 }
39 }
40 let mut map = serializer.serialize_map(Some(self.len()))?;
41 for (k, v) in self.iter() {
42 K::Container::zvl_get_as_t(k, |k| map.serialize_key(k))?;
43 V::Container::zvl_get_as_t(v, |v| map.serialize_value(v))?;
44 }
45 map.end()
46 } else {
47 (&self.keys, &self.values).serialize(serializer)
48 }
49 }
50}
51
52#[cfg(feature = "serde")]
54impl<'a, K, V> Serialize for ZeroMapBorrowed<'a, K, V>
55where
56 K: ZeroMapKV<'a> + Serialize + ?Sized + Ord,
57 V: ZeroMapKV<'a> + Serialize + ?Sized,
58 K::Container: Serialize,
59 V::Container: Serialize,
60{
61 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
62 where
63 S: Serializer,
64 {
65 ZeroMap::<K, V>::from(*self).serialize(serializer)
66 }
67}
68
69struct ZeroMapMapVisitor<'a, K, V>
71where
72 K: ZeroMapKV<'a> + ?Sized + Ord,
73 V: ZeroMapKV<'a> + ?Sized,
74{
75 #[allow(clippy::type_complexity)] marker: PhantomData<fn() -> (&'a K::OwnedType, &'a V::OwnedType)>,
77}
78
79impl<'a, K, V> ZeroMapMapVisitor<'a, K, V>
80where
81 K: ZeroMapKV<'a> + ?Sized + Ord,
82 V: ZeroMapKV<'a> + ?Sized,
83{
84 fn new() -> Self {
85 ZeroMapMapVisitor {
86 marker: PhantomData,
87 }
88 }
89}
90
91impl<'a, 'de, K, V> Visitor<'de> for ZeroMapMapVisitor<'a, K, V>
92where
93 K: ZeroMapKV<'a> + Ord + ?Sized,
94 V: ZeroMapKV<'a> + ?Sized,
95 K::OwnedType: Deserialize<'de>,
96 V::OwnedType: Deserialize<'de>,
97{
98 type Value = ZeroMap<'a, K, V>;
99
100 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
101 formatter.write_str("a map produced by ZeroMap")
102 }
103
104 fn visit_seq<S>(self, mut access: S) -> Result<Self::Value, S::Error>
105 where
106 S: SeqAccess<'de>,
107 {
108 let mut map = ZeroMap::with_capacity(access.size_hint().unwrap_or(0));
109
110 while let Some((key, value)) = access.next_element::<(K::OwnedType, V::OwnedType)>()? {
113 if map
117 .try_append(
118 K::Container::owned_as_t(&key),
119 V::Container::owned_as_t(&value),
120 )
121 .is_some()
122 {
123 return Err(de::Error::custom(
124 "ZeroMap's keys must be sorted while deserializing",
125 ));
126 }
127 }
128
129 Ok(map)
130 }
131
132 fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
133 where
134 M: MapAccess<'de>,
135 {
136 let mut map = ZeroMap::with_capacity(access.size_hint().unwrap_or(0));
137
138 while let Some((key, value)) = access.next_entry::<K::OwnedType, V::OwnedType>()? {
141 if map
145 .try_append(
146 K::Container::owned_as_t(&key),
147 V::Container::owned_as_t(&value),
148 )
149 .is_some()
150 {
151 return Err(de::Error::custom(
152 "ZeroMap's keys must be sorted while deserializing",
153 ));
154 }
155 }
156
157 Ok(map)
158 }
159}
160
161impl<'de, 'a, K, V> Deserialize<'de> for ZeroMap<'a, K, V>
163where
164 K: ZeroMapKV<'a> + Ord + ?Sized,
165 V: ZeroMapKV<'a> + ?Sized,
166 K::Container: Deserialize<'de>,
167 V::Container: Deserialize<'de>,
168 K::OwnedType: Deserialize<'de>,
169 V::OwnedType: Deserialize<'de>,
170 'de: 'a,
171{
172 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
173 where
174 D: Deserializer<'de>,
175 {
176 if deserializer.is_human_readable() {
177 deserializer.deserialize_any(ZeroMapMapVisitor::<'a, K, V>::new())
178 } else {
179 let (keys, values): (K::Container, V::Container) =
180 Deserialize::deserialize(deserializer)?;
181 if keys.zvl_len() != values.zvl_len() {
182 return Err(de::Error::custom(
183 "Mismatched key and value sizes in ZeroMap",
184 ));
185 }
186 debug_assert!(keys.zvl_is_ascending());
188 Ok(Self { keys, values })
189 }
190 }
191}
192
193impl<'de, 'a, K, V> Deserialize<'de> for ZeroMapBorrowed<'a, K, V>
195where
196 K: ZeroMapKV<'a> + Ord + ?Sized,
197 V: ZeroMapKV<'a> + ?Sized,
198 K::Container: Deserialize<'de>,
199 V::Container: Deserialize<'de>,
200 K::OwnedType: Deserialize<'de>,
201 V::OwnedType: Deserialize<'de>,
202 'de: 'a,
203{
204 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
205 where
206 D: Deserializer<'de>,
207 {
208 if deserializer.is_human_readable() {
209 Err(de::Error::custom(
210 "ZeroMapBorrowed cannot be deserialized from human-readable formats",
211 ))
212 } else {
213 let deserialized: ZeroMap<'a, K, V> = ZeroMap::deserialize(deserializer)?;
214 let keys = if let Some(keys) = deserialized.keys.zvl_as_borrowed_inner() {
215 keys
216 } else {
217 return Err(de::Error::custom(
218 "ZeroMapBorrowed can only deserialize in zero-copy ways",
219 ));
220 };
221 let values = if let Some(values) = deserialized.values.zvl_as_borrowed_inner() {
222 values
223 } else {
224 return Err(de::Error::custom(
225 "ZeroMapBorrowed can only deserialize in zero-copy ways",
226 ));
227 };
228 Ok(Self { keys, values })
229 }
230 }
231}
232
233#[cfg(test)]
234#[allow(non_camel_case_types)]
235mod test {
236 use crate::{map::ZeroMapBorrowed, ZeroMap};
237
238 #[derive(serde::Serialize, serde::Deserialize)]
239 struct DeriveTest_ZeroMap<'data> {
240 #[serde(borrow)]
241 _data: ZeroMap<'data, str, [u8]>,
242 }
243
244 #[derive(serde::Serialize, serde::Deserialize)]
245 struct DeriveTest_ZeroMapBorrowed<'data> {
246 #[serde(borrow)]
247 _data: ZeroMapBorrowed<'data, str, [u8]>,
248 }
249
250 const JSON_STR: &str = "{\"1\":\"uno\",\"2\":\"dos\",\"3\":\"tres\"}";
251 const BINCODE_BYTES: &[u8] = &[
252 12, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 3, 0,
253 3, 0, 6, 0, 117, 110, 111, 100, 111, 115, 116, 114, 101, 115,
254 ];
255
256 fn make_map() -> ZeroMap<'static, u32, str> {
257 let mut map = ZeroMap::new();
258 map.insert(&1, "uno");
259 map.insert(&2, "dos");
260 map.insert(&3, "tres");
261 map
262 }
263
264 #[test]
265 fn test_serde_json() {
266 let map = make_map();
267 let json_str = serde_json::to_string(&map).expect("serialize");
268 assert_eq!(JSON_STR, json_str);
269 let new_map: ZeroMap<u32, str> = serde_json::from_str(&json_str).expect("deserialize");
270 assert_eq!(
271 new_map.iter().collect::<Vec<_>>(),
272 map.iter().collect::<Vec<_>>()
273 );
274 }
275
276 #[test]
277 fn test_serde_json_complex_key() {
278 let mut map = ZeroMap::new();
279 map.insert(&(1, 1), "uno");
280 map.insert(&(2, 2), "dos");
281 map.insert(&(3, 3), "tres");
282 let json_str = serde_json::to_string(&map).expect("serialize");
283 assert_eq!(
284 json_str,
285 "[[[1,1],\"uno\"],[[2,2],\"dos\"],[[3,3],\"tres\"]]"
286 );
287 let new_map: ZeroMap<(u32, u32), str> =
288 serde_json::from_str(&json_str).expect("deserialize");
289 assert_eq!(
290 new_map.iter().collect::<Vec<_>>(),
291 map.iter().collect::<Vec<_>>()
292 );
293 }
294
295 #[test]
296 fn test_bincode() {
297 let map = make_map();
298 let bincode_bytes = bincode::serialize(&map).expect("serialize");
299 assert_eq!(BINCODE_BYTES, bincode_bytes);
300 let new_map: ZeroMap<u32, str> = bincode::deserialize(&bincode_bytes).expect("deserialize");
301 assert_eq!(
302 new_map.iter().collect::<Vec<_>>(),
303 map.iter().collect::<Vec<_>>()
304 );
305
306 let new_map: ZeroMapBorrowed<u32, str> =
307 bincode::deserialize(&bincode_bytes).expect("deserialize");
308 assert_eq!(
309 new_map.iter().collect::<Vec<_>>(),
310 map.iter().collect::<Vec<_>>()
311 );
312 }
313}