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 #[expect(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 #[expect(
240 dead_code,
241 reason = "Tests compatibility of custom impl with Serde derive."
242 )]
243 struct DeriveTest_ZeroMap<'data> {
244 #[serde(borrow)]
245 _data: ZeroMap<'data, str, [u8]>,
246 }
247
248 #[derive(serde::Serialize, serde::Deserialize)]
249 #[expect(
250 dead_code,
251 reason = "Tests compatibility of custom impl with Serde derive."
252 )]
253 struct DeriveTest_ZeroMapBorrowed<'data> {
254 #[serde(borrow)]
255 _data: ZeroMapBorrowed<'data, str, [u8]>,
256 }
257
258 const JSON_STR: &str = "{\"1\":\"uno\",\"2\":\"dos\",\"3\":\"tres\"}";
259 const BINCODE_BYTES: &[u8] = &[
260 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,
261 3, 0, 6, 0, 117, 110, 111, 100, 111, 115, 116, 114, 101, 115,
262 ];
263
264 fn make_map() -> ZeroMap<'static, u32, str> {
265 let mut map = ZeroMap::new();
266 map.insert(&1, "uno");
267 map.insert(&2, "dos");
268 map.insert(&3, "tres");
269 map
270 }
271
272 #[test]
273 fn test_serde_json() {
274 let map = make_map();
275 let json_str = serde_json::to_string(&map).expect("serialize");
276 assert_eq!(JSON_STR, json_str);
277 let new_map: ZeroMap<u32, str> = serde_json::from_str(&json_str).expect("deserialize");
278 assert_eq!(
279 new_map.iter().collect::<Vec<_>>(),
280 map.iter().collect::<Vec<_>>()
281 );
282 }
283
284 #[test]
285 fn test_serde_json_complex_key() {
286 let mut map = ZeroMap::new();
287 map.insert(&(1, 1), "uno");
288 map.insert(&(2, 2), "dos");
289 map.insert(&(3, 3), "tres");
290 let json_str = serde_json::to_string(&map).expect("serialize");
291 assert_eq!(
292 json_str,
293 "[[[1,1],\"uno\"],[[2,2],\"dos\"],[[3,3],\"tres\"]]"
294 );
295 let new_map: ZeroMap<(u32, u32), str> =
296 serde_json::from_str(&json_str).expect("deserialize");
297 assert_eq!(
298 new_map.iter().collect::<Vec<_>>(),
299 map.iter().collect::<Vec<_>>()
300 );
301 }
302
303 #[test]
304 fn test_bincode() {
305 let map = make_map();
306 let bincode_bytes = bincode::serialize(&map).expect("serialize");
307 assert_eq!(BINCODE_BYTES, bincode_bytes);
308 let new_map: ZeroMap<u32, str> = bincode::deserialize(&bincode_bytes).expect("deserialize");
309 assert_eq!(
310 new_map.iter().collect::<Vec<_>>(),
311 map.iter().collect::<Vec<_>>()
312 );
313
314 let new_map: ZeroMapBorrowed<u32, str> =
315 bincode::deserialize(&bincode_bytes).expect("deserialize");
316 assert_eq!(
317 new_map.iter().collect::<Vec<_>>(),
318 map.iter().collect::<Vec<_>>()
319 );
320 }
321}