• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // This file is part of ICU4X. For terms of use, please see the file
2 // called LICENSE at the top level of the ICU4X source tree
3 // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4 
5 use crate::builder::bytestr::ByteStr;
6 use crate::options::ZeroTrieWithOptions;
7 use crate::zerotrie::ZeroTrieFlavor;
8 use crate::ZeroAsciiIgnoreCaseTrie;
9 use crate::ZeroTrie;
10 use crate::ZeroTrieExtendedCapacity;
11 use crate::ZeroTriePerfectHash;
12 use crate::ZeroTrieSimpleAscii;
13 use alloc::boxed::Box;
14 use alloc::vec::Vec;
15 use core::fmt;
16 use litemap::LiteMap;
17 use serde::de::Error;
18 use serde::de::Visitor;
19 use serde::Deserialize;
20 use serde::Deserializer;
21 use serde::Serialize;
22 use serde::Serializer;
23 
24 struct ByteStrVisitor;
25 impl<'de> Visitor<'de> for ByteStrVisitor {
26     type Value = Box<[u8]>;
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result27     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
28         write!(formatter, "a slice of borrowed bytes or a string")
29     }
visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>30     fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> {
31         Ok(Box::from(v))
32     }
visit_str<E>(self, v: &str) -> Result<Self::Value, E>33     fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> {
34         Ok(Box::from(v.as_bytes()))
35     }
visit_seq<A>(self, mut v: A) -> Result<Self::Value, A::Error> where A: serde::de::SeqAccess<'de>,36     fn visit_seq<A>(self, mut v: A) -> Result<Self::Value, A::Error>
37     where
38         A: serde::de::SeqAccess<'de>,
39     {
40         let mut result = Vec::with_capacity(v.size_hint().unwrap_or(0));
41         while let Some(x) = v.next_element::<u8>()? {
42             result.push(x);
43         }
44         Ok(Box::from(result))
45     }
46 }
47 
48 impl<'data, 'de: 'data> Deserialize<'de> for &'data ByteStr {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,49     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
50     where
51         D: Deserializer<'de>,
52     {
53         let s = <&'data [u8]>::deserialize(deserializer)?;
54         Ok(ByteStr::from_bytes(s))
55     }
56 }
57 
58 impl<'de> Deserialize<'de> for Box<ByteStr> {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,59     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
60     where
61         D: Deserializer<'de>,
62     {
63         if deserializer.is_human_readable() {
64             let s = deserializer.deserialize_any(ByteStrVisitor)?;
65             Ok(ByteStr::from_boxed_bytes(s))
66         } else {
67             let s = Vec::<u8>::deserialize(deserializer)?;
68             Ok(ByteStr::from_boxed_bytes(s.into_boxed_slice()))
69         }
70     }
71 }
72 
73 impl Serialize for &ByteStr {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,74     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
75     where
76         S: Serializer,
77     {
78         let bytes = self.as_bytes();
79         if serializer.is_human_readable() {
80             match core::str::from_utf8(bytes) {
81                 Ok(s) => serializer.serialize_str(s),
82                 Err(_) => serializer.serialize_bytes(bytes),
83             }
84         } else {
85             serializer.serialize_bytes(bytes)
86         }
87     }
88 }
89 
90 impl<'data, 'de: 'data, Store> Deserialize<'de> for ZeroTrieSimpleAscii<Store>
91 where
92     // DISCUSS: There are several possibilities for the bounds here that would
93     // get the job done. I could look for Deserialize, but this would require
94     // creating a custom Deserializer for the map case. I also considered
95     // introducing a new trait instead of relying on From.
96     Store: From<&'data [u8]> + From<Vec<u8>> + 'data,
97 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,98     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
99     where
100         D: Deserializer<'de>,
101     {
102         if deserializer.is_human_readable() {
103             let lm = LiteMap::<Box<ByteStr>, usize>::deserialize(deserializer)?;
104             ZeroTrieSimpleAscii::try_from_serde_litemap(&lm)
105                 .map_err(D::Error::custom)
106                 .map(|trie| trie.convert_store())
107         } else {
108             // Note: `impl Deserialize for &[u8]` uses visit_borrowed_bytes
109             let (flags, trie_bytes) = <(u8, &[u8])>::deserialize(deserializer)?;
110             if Self::OPTIONS.to_u8_flags() != flags {
111                 return Err(D::Error::custom("invalid ZeroTrie tag"));
112             };
113             Ok(ZeroTrieSimpleAscii::from_store(Store::from(trie_bytes)))
114         }
115     }
116 }
117 
118 impl<Store> Serialize for ZeroTrieSimpleAscii<Store>
119 where
120     Store: AsRef<[u8]>,
121 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,122     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
123     where
124         S: Serializer,
125     {
126         if serializer.is_human_readable() {
127             let lm = self.to_litemap();
128             lm.serialize(serializer)
129         } else {
130             // Note: `impl Serialize for ByteStr` uses `serialize_bytes`
131             (Self::FLAGS, ByteStr::from_bytes(self.as_bytes())).serialize(serializer)
132         }
133     }
134 }
135 
136 impl<'de, 'data, Store> Deserialize<'de> for ZeroAsciiIgnoreCaseTrie<Store>
137 where
138     'de: 'data,
139     // DISCUSS: There are several possibilities for the bounds here that would
140     // get the job done. I could look for Deserialize, but this would require
141     // creating a custom Deserializer for the map case. I also considered
142     // introducing a new trait instead of relying on From.
143     Store: From<&'data [u8]> + From<Vec<u8>> + 'data,
144 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,145     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
146     where
147         D: Deserializer<'de>,
148     {
149         if deserializer.is_human_readable() {
150             let lm = LiteMap::<Box<ByteStr>, usize>::deserialize(deserializer)?;
151             ZeroAsciiIgnoreCaseTrie::try_from_serde_litemap(&lm)
152                 .map_err(D::Error::custom)
153                 .map(|trie| trie.convert_store())
154         } else {
155             // Note: `impl Deserialize for &[u8]` uses visit_borrowed_bytes
156             let (flags, trie_bytes) = <(u8, &[u8])>::deserialize(deserializer)?;
157             if Self::OPTIONS.to_u8_flags() != flags {
158                 return Err(D::Error::custom("invalid ZeroTrie tag"));
159             }
160             Ok(ZeroAsciiIgnoreCaseTrie::from_store(Store::from(trie_bytes)))
161         }
162     }
163 }
164 
165 impl<Store> Serialize for ZeroAsciiIgnoreCaseTrie<Store>
166 where
167     Store: AsRef<[u8]>,
168 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,169     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
170     where
171         S: Serializer,
172     {
173         if serializer.is_human_readable() {
174             let lm = self.to_litemap();
175             lm.serialize(serializer)
176         } else {
177             // Note: `impl Serialize for ByteStr` uses `serialize_bytes`
178             (
179                 Self::OPTIONS.to_u8_flags(),
180                 ByteStr::from_bytes(self.as_bytes()),
181             )
182                 .serialize(serializer)
183         }
184     }
185 }
186 
187 impl<'de, 'data, Store> Deserialize<'de> for ZeroTriePerfectHash<Store>
188 where
189     'de: 'data,
190     Store: From<&'data [u8]> + From<Vec<u8>> + 'data,
191 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,192     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
193     where
194         D: Deserializer<'de>,
195     {
196         if deserializer.is_human_readable() {
197             let lm = LiteMap::<Box<ByteStr>, usize>::deserialize(deserializer)?;
198             ZeroTriePerfectHash::try_from_serde_litemap(&lm)
199                 .map_err(D::Error::custom)
200                 .map(|trie| trie.convert_store())
201         } else {
202             // Note: `impl Deserialize for &[u8]` uses visit_borrowed_bytes
203             let (flags, trie_bytes) = <(u8, &[u8])>::deserialize(deserializer)?;
204             if Self::OPTIONS.to_u8_flags() != flags {
205                 return Err(D::Error::custom("invalid ZeroTrie tag"));
206             }
207             Ok(ZeroTriePerfectHash::from_store(Store::from(trie_bytes)))
208         }
209     }
210 }
211 
212 impl<Store> Serialize for ZeroTriePerfectHash<Store>
213 where
214     Store: AsRef<[u8]>,
215 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,216     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
217     where
218         S: Serializer,
219     {
220         if serializer.is_human_readable() {
221             let lm = self.to_litemap();
222             let lm = lm
223                 .iter()
224                 .map(|(k, v)| (ByteStr::from_bytes(k), v))
225                 .collect::<LiteMap<_, _>>();
226             lm.serialize(serializer)
227         } else {
228             // Note: `impl Serialize for ByteStr` uses `serialize_bytes`
229             (
230                 Self::OPTIONS.to_u8_flags(),
231                 ByteStr::from_bytes(self.as_bytes()),
232             )
233                 .serialize(serializer)
234         }
235     }
236 }
237 
238 impl<'de, 'data, Store> Deserialize<'de> for ZeroTrieExtendedCapacity<Store>
239 where
240     'de: 'data,
241     Store: From<&'data [u8]> + From<Vec<u8>> + 'data,
242 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,243     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
244     where
245         D: Deserializer<'de>,
246     {
247         if deserializer.is_human_readable() {
248             let lm = LiteMap::<Box<ByteStr>, usize>::deserialize(deserializer)?;
249             ZeroTrieExtendedCapacity::try_from_serde_litemap(&lm)
250                 .map_err(D::Error::custom)
251                 .map(|trie| trie.convert_store())
252         } else {
253             // Note: `impl Deserialize for &[u8]` uses visit_borrowed_bytes
254             let (flags, trie_bytes) = <(u8, &[u8])>::deserialize(deserializer)?;
255             if Self::OPTIONS.to_u8_flags() != flags {
256                 return Err(D::Error::custom("invalid ZeroTrie tag"));
257             }
258             Ok(ZeroTrieExtendedCapacity::from_store(Store::from(
259                 trie_bytes,
260             )))
261         }
262     }
263 }
264 
265 impl<Store> Serialize for ZeroTrieExtendedCapacity<Store>
266 where
267     Store: AsRef<[u8]>,
268 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,269     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
270     where
271         S: Serializer,
272     {
273         if serializer.is_human_readable() {
274             let lm = self.to_litemap();
275             let lm = lm
276                 .iter()
277                 .map(|(k, v)| (ByteStr::from_bytes(k), v))
278                 .collect::<LiteMap<_, _>>();
279             lm.serialize(serializer)
280         } else {
281             // Note: `impl Serialize for ByteStr` uses `serialize_bytes`
282             (
283                 Self::OPTIONS.to_u8_flags(),
284                 ByteStr::from_bytes(self.as_bytes()),
285             )
286                 .serialize(serializer)
287         }
288     }
289 }
290 
291 impl<'de, 'data, Store> Deserialize<'de> for ZeroTrie<Store>
292 where
293     'de: 'data,
294     Store: From<&'data [u8]> + From<Vec<u8>> + 'data,
295 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,296     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
297     where
298         D: Deserializer<'de>,
299     {
300         if deserializer.is_human_readable() {
301             let lm = LiteMap::<Box<ByteStr>, usize>::deserialize(deserializer)?;
302             ZeroTrie::<Vec<u8>>::try_from(&lm)
303                 .map_err(D::Error::custom)
304                 .map(|trie| trie.convert_store())
305         } else {
306             // Note: `impl Deserialize for &[u8]` uses visit_borrowed_bytes
307             let bytes = <&[u8]>::deserialize(deserializer)?;
308             let (tag, trie_bytes) = bytes
309                 .split_first()
310                 .ok_or(D::Error::custom("expected at least 1 byte for ZeroTrie"))?;
311             let store = Store::from(trie_bytes);
312             let zerotrie = if *tag == ZeroTrieSimpleAscii::<u8>::OPTIONS.to_u8_flags() {
313                 ZeroTrieSimpleAscii::from_store(store).into_zerotrie()
314             } else if *tag == ZeroTriePerfectHash::<u8>::OPTIONS.to_u8_flags() {
315                 ZeroTriePerfectHash::from_store(store).into_zerotrie()
316             } else if *tag == ZeroTrieExtendedCapacity::<u8>::OPTIONS.to_u8_flags() {
317                 ZeroTrieExtendedCapacity::from_store(store).into_zerotrie()
318             } else {
319                 return Err(D::Error::custom("invalid ZeroTrie tag"));
320             };
321             Ok(zerotrie)
322         }
323     }
324 }
325 
326 impl<Store> Serialize for ZeroTrie<Store>
327 where
328     Store: AsRef<[u8]>,
329 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,330     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
331     where
332         S: Serializer,
333     {
334         if serializer.is_human_readable() {
335             let lm = self.to_litemap();
336             let lm = lm
337                 .iter()
338                 .map(|(k, v)| (ByteStr::from_bytes(k), v))
339                 .collect::<LiteMap<_, _>>();
340             lm.serialize(serializer)
341         } else {
342             let (tag, bytes) = match &self.0 {
343                 ZeroTrieFlavor::SimpleAscii(t) => (
344                     ZeroTrieSimpleAscii::<u8>::OPTIONS.to_u8_flags(),
345                     t.as_bytes(),
346                 ),
347                 ZeroTrieFlavor::PerfectHash(t) => (
348                     ZeroTriePerfectHash::<u8>::OPTIONS.to_u8_flags(),
349                     t.as_bytes(),
350                 ),
351                 ZeroTrieFlavor::ExtendedCapacity(t) => (
352                     ZeroTrieExtendedCapacity::<u8>::OPTIONS.to_u8_flags(),
353                     t.as_bytes(),
354                 ),
355             };
356             let mut all_in_one_vec = Vec::with_capacity(bytes.len() + 1);
357             all_in_one_vec.push(tag);
358             all_in_one_vec.extend(bytes);
359             serializer.serialize_bytes(&all_in_one_vec)
360         }
361     }
362 }
363 
364 #[cfg(test)]
365 mod testdata {
366     include!("../tests/data/data.rs");
367 }
368 
369 #[cfg(test)]
370 mod tests {
371     use super::*;
372     use alloc::borrow::Cow;
373 
374     #[derive(Serialize, Deserialize)]
375     pub struct ZeroTrieSimpleAsciiCow<'a> {
376         #[serde(borrow)]
377         trie: ZeroTrieSimpleAscii<Cow<'a, [u8]>>,
378     }
379 
380     #[test]
test_serde_simpleascii_cow()381     pub fn test_serde_simpleascii_cow() {
382         let trie = ZeroTrieSimpleAscii::from_store(Cow::from(testdata::basic::TRIE_ASCII));
383         let original = ZeroTrieSimpleAsciiCow { trie };
384         let json_str = serde_json::to_string(&original).unwrap();
385         let bincode_bytes = bincode::serialize(&original).unwrap();
386         let rmp_bytes = rmp_serde::to_vec(&original).unwrap();
387 
388         assert_eq!(json_str, testdata::basic::JSON_STR_ASCII);
389         assert_eq!(&bincode_bytes[0..9], &[0, 26, 0, 0, 0, 0, 0, 0, 0]);
390         assert_eq!(&bincode_bytes[9..], testdata::basic::BINCODE_BYTES_ASCII);
391         assert_eq!(&rmp_bytes[0..5], &[145, 146, 0, 196, 26]);
392         assert_eq!(&rmp_bytes[5..], testdata::basic::BINCODE_BYTES_ASCII);
393 
394         let json_recovered: ZeroTrieSimpleAsciiCow = serde_json::from_str(&json_str).unwrap();
395         let bincode_recovered: ZeroTrieSimpleAsciiCow =
396             bincode::deserialize(&bincode_bytes).unwrap();
397         let rmp_recovered: ZeroTrieSimpleAsciiCow = rmp_serde::from_slice(&rmp_bytes).unwrap();
398 
399         assert_eq!(original.trie, json_recovered.trie);
400         assert_eq!(original.trie, bincode_recovered.trie);
401         assert_eq!(original.trie, rmp_recovered.trie);
402 
403         assert!(matches!(json_recovered.trie.into_store(), Cow::Owned(_)));
404         assert!(matches!(
405             bincode_recovered.trie.into_store(),
406             Cow::Borrowed(_)
407         ));
408     }
409 
410     #[derive(Serialize, Deserialize)]
411     pub struct ZeroAsciiIgnoreCaseTrieCow<'a> {
412         #[serde(borrow)]
413         trie: ZeroAsciiIgnoreCaseTrie<Cow<'a, [u8]>>,
414     }
415 
416     #[test]
test_serde_asciiignorecase_cow()417     pub fn test_serde_asciiignorecase_cow() {
418         let trie = ZeroAsciiIgnoreCaseTrie::from_store(Cow::from(testdata::basic::TRIE_ASCII));
419         let original = ZeroAsciiIgnoreCaseTrieCow { trie };
420         let json_str = serde_json::to_string(&original).unwrap();
421         let bincode_bytes = bincode::serialize(&original).unwrap();
422 
423         assert_eq!(json_str, testdata::basic::JSON_STR_ASCII);
424         assert_eq!(&bincode_bytes[0..9], &[8, 26, 0, 0, 0, 0, 0, 0, 0]);
425         assert_eq!(&bincode_bytes[9..], testdata::basic::BINCODE_BYTES_ASCII);
426 
427         let json_recovered: ZeroAsciiIgnoreCaseTrieCow = serde_json::from_str(&json_str).unwrap();
428         let bincode_recovered: ZeroAsciiIgnoreCaseTrieCow =
429             bincode::deserialize(&bincode_bytes).unwrap();
430 
431         assert_eq!(original.trie, json_recovered.trie);
432         assert_eq!(original.trie, bincode_recovered.trie);
433 
434         assert!(matches!(json_recovered.trie.into_store(), Cow::Owned(_)));
435         assert!(matches!(
436             bincode_recovered.trie.into_store(),
437             Cow::Borrowed(_)
438         ));
439     }
440 
441     #[derive(Serialize, Deserialize)]
442     pub struct ZeroTriePerfectHashCow<'a> {
443         #[serde(borrow)]
444         trie: ZeroTriePerfectHash<Cow<'a, [u8]>>,
445     }
446 
447     #[test]
test_serde_perfecthash_cow()448     pub fn test_serde_perfecthash_cow() {
449         let trie = ZeroTriePerfectHash::from_store(Cow::from(testdata::basic::TRIE_ASCII));
450         let original = ZeroTriePerfectHashCow { trie };
451         let json_str = serde_json::to_string(&original).unwrap();
452         let bincode_bytes = bincode::serialize(&original).unwrap();
453 
454         assert_eq!(json_str, testdata::basic::JSON_STR_ASCII);
455         assert_eq!(&bincode_bytes[0..9], &[3, 26, 0, 0, 0, 0, 0, 0, 0]);
456         assert_eq!(&bincode_bytes[9..], testdata::basic::BINCODE_BYTES_ASCII);
457 
458         let json_recovered: ZeroTriePerfectHashCow = serde_json::from_str(&json_str).unwrap();
459         let bincode_recovered: ZeroTriePerfectHashCow =
460             bincode::deserialize(&bincode_bytes).unwrap();
461 
462         assert_eq!(original.trie, json_recovered.trie);
463         assert_eq!(original.trie, bincode_recovered.trie);
464 
465         assert!(matches!(json_recovered.trie.into_store(), Cow::Owned(_)));
466         assert!(matches!(
467             bincode_recovered.trie.into_store(),
468             Cow::Borrowed(_)
469         ));
470     }
471 
472     #[test]
test_serde_perfecthash_cow_u()473     pub fn test_serde_perfecthash_cow_u() {
474         let trie = ZeroTriePerfectHash::from_store(Cow::from(testdata::basic::TRIE_UNICODE));
475         let original = ZeroTriePerfectHashCow { trie };
476         let json_str = serde_json::to_string(&original).unwrap();
477         let bincode_bytes = bincode::serialize(&original).unwrap();
478 
479         assert_eq!(json_str, testdata::basic::JSON_STR_UNICODE);
480         assert_eq!(&bincode_bytes[0..9], &[3, 39, 0, 0, 0, 0, 0, 0, 0]);
481         assert_eq!(&bincode_bytes[9..], testdata::basic::BINCODE_BYTES_UNICODE);
482 
483         let json_recovered: ZeroTriePerfectHashCow = serde_json::from_str(&json_str).unwrap();
484         let bincode_recovered: ZeroTriePerfectHashCow =
485             bincode::deserialize(&bincode_bytes).unwrap();
486 
487         assert_eq!(original.trie, json_recovered.trie);
488         assert_eq!(original.trie, bincode_recovered.trie);
489 
490         assert!(matches!(json_recovered.trie.into_store(), Cow::Owned(_)));
491         assert!(matches!(
492             bincode_recovered.trie.into_store(),
493             Cow::Borrowed(_)
494         ));
495     }
496 
497     #[test]
test_serde_perfecthash_cow_bin()498     pub fn test_serde_perfecthash_cow_bin() {
499         let trie = ZeroTriePerfectHash::from_store(Cow::from(testdata::basic::TRIE_BINARY));
500         let original = ZeroTriePerfectHashCow { trie };
501         let json_str = serde_json::to_string(&original).unwrap();
502         let bincode_bytes = bincode::serialize(&original).unwrap();
503 
504         assert_eq!(json_str, testdata::basic::JSON_STR_BINARY);
505         assert_eq!(&bincode_bytes[0..9], &[3, 26, 0, 0, 0, 0, 0, 0, 0]);
506         assert_eq!(&bincode_bytes[9..], testdata::basic::BINCODE_BYTES_BINARY);
507 
508         let json_recovered: ZeroTriePerfectHashCow = serde_json::from_str(&json_str).unwrap();
509         let bincode_recovered: ZeroTriePerfectHashCow =
510             bincode::deserialize(&bincode_bytes).unwrap();
511 
512         assert_eq!(original.trie, json_recovered.trie);
513         assert_eq!(original.trie, bincode_recovered.trie);
514 
515         assert!(matches!(json_recovered.trie.into_store(), Cow::Owned(_)));
516         assert!(matches!(
517             bincode_recovered.trie.into_store(),
518             Cow::Borrowed(_)
519         ));
520     }
521 
522     #[derive(Serialize, Deserialize)]
523     pub struct ZeroTrieAnyCow<'a> {
524         #[serde(borrow)]
525         trie: ZeroTrie<Cow<'a, [u8]>>,
526     }
527 
528     #[test]
test_serde_any_cow()529     pub fn test_serde_any_cow() {
530         let trie =
531             ZeroTrieSimpleAscii::from_store(Cow::from(testdata::basic::TRIE_ASCII)).into_zerotrie();
532         let original = ZeroTrieAnyCow { trie };
533         let json_str = serde_json::to_string(&original).unwrap();
534         let bincode_bytes = bincode::serialize(&original).unwrap();
535 
536         assert_eq!(json_str, testdata::basic::JSON_STR_ASCII);
537         assert_eq!(&bincode_bytes[0..9], &[27, 0, 0, 0, 0, 0, 0, 0, 0]);
538         assert_eq!(&bincode_bytes[9..], testdata::basic::BINCODE_BYTES_ASCII);
539 
540         let json_recovered: ZeroTrieAnyCow = serde_json::from_str(&json_str).unwrap();
541         let bincode_recovered: ZeroTrieAnyCow = bincode::deserialize(&bincode_bytes).unwrap();
542 
543         assert_eq!(original.trie, json_recovered.trie);
544         assert_eq!(original.trie, bincode_recovered.trie);
545 
546         assert!(matches!(json_recovered.trie.into_store(), Cow::Owned(_)));
547         assert!(matches!(
548             bincode_recovered.trie.into_store(),
549             Cow::Borrowed(_)
550         ));
551     }
552 
553     #[test]
test_serde_any_cow_u()554     pub fn test_serde_any_cow_u() {
555         let trie = ZeroTriePerfectHash::from_store(Cow::from(testdata::basic::TRIE_UNICODE))
556             .into_zerotrie();
557         let original = ZeroTrieAnyCow { trie };
558         let json_str = serde_json::to_string(&original).unwrap();
559         let bincode_bytes = bincode::serialize(&original).unwrap();
560 
561         assert_eq!(json_str, testdata::basic::JSON_STR_UNICODE);
562         assert_eq!(&bincode_bytes[0..9], &[40, 0, 0, 0, 0, 0, 0, 0, 3]);
563         assert_eq!(&bincode_bytes[9..], testdata::basic::BINCODE_BYTES_UNICODE);
564 
565         let json_recovered: ZeroTrieAnyCow = serde_json::from_str(&json_str).unwrap();
566         let bincode_recovered: ZeroTrieAnyCow = bincode::deserialize(&bincode_bytes).unwrap();
567 
568         assert_eq!(original.trie, json_recovered.trie);
569         assert_eq!(original.trie, bincode_recovered.trie);
570 
571         assert!(matches!(json_recovered.trie.into_store(), Cow::Owned(_)));
572         assert!(matches!(
573             bincode_recovered.trie.into_store(),
574             Cow::Borrowed(_)
575         ));
576     }
577 }
578 
579 #[cfg(test)]
580 #[cfg(feature = "zerovec")]
581 mod tests_zerovec {
582     use super::*;
583     use zerovec::ZeroVec;
584 
585     #[derive(Serialize, Deserialize)]
586     pub struct ZeroTrieSimpleAsciiZeroVec<'a> {
587         #[serde(borrow)]
588         trie: ZeroTrieSimpleAscii<ZeroVec<'a, u8>>,
589     }
590 
591     #[test]
test_serde_simpleascii_zerovec()592     pub fn test_serde_simpleascii_zerovec() {
593         let trie =
594             ZeroTrieSimpleAscii::from_store(ZeroVec::new_borrowed(testdata::basic::TRIE_ASCII));
595         let original = ZeroTrieSimpleAsciiZeroVec { trie };
596         let json_str = serde_json::to_string(&original).unwrap();
597         let bincode_bytes = bincode::serialize(&original).unwrap();
598 
599         assert_eq!(json_str, testdata::basic::JSON_STR_ASCII);
600         assert_eq!(&bincode_bytes[0..9], &[0, 26, 0, 0, 0, 0, 0, 0, 0]);
601         assert_eq!(&bincode_bytes[9..], testdata::basic::BINCODE_BYTES_ASCII);
602 
603         let json_recovered: ZeroTrieSimpleAsciiZeroVec = serde_json::from_str(&json_str).unwrap();
604         let bincode_recovered: ZeroTrieSimpleAsciiZeroVec =
605             bincode::deserialize(&bincode_bytes).unwrap();
606 
607         assert_eq!(original.trie, json_recovered.trie);
608         assert_eq!(original.trie, bincode_recovered.trie);
609 
610         assert!(json_recovered.trie.into_store().is_owned());
611         assert!(!bincode_recovered.trie.into_store().is_owned());
612     }
613 
614     #[derive(Serialize, Deserialize)]
615     pub struct ZeroTriePerfectHashZeroVec<'a> {
616         #[serde(borrow)]
617         trie: ZeroTriePerfectHash<ZeroVec<'a, u8>>,
618     }
619 
620     #[test]
test_serde_perfecthash_zerovec()621     pub fn test_serde_perfecthash_zerovec() {
622         let trie =
623             ZeroTriePerfectHash::from_store(ZeroVec::new_borrowed(testdata::basic::TRIE_ASCII));
624         let original = ZeroTriePerfectHashZeroVec { trie };
625         let json_str = serde_json::to_string(&original).unwrap();
626         let bincode_bytes = bincode::serialize(&original).unwrap();
627 
628         assert_eq!(json_str, testdata::basic::JSON_STR_ASCII);
629         assert_eq!(&bincode_bytes[0..9], &[3, 26, 0, 0, 0, 0, 0, 0, 0]);
630         assert_eq!(&bincode_bytes[9..], testdata::basic::BINCODE_BYTES_ASCII);
631 
632         let json_recovered: ZeroTriePerfectHashZeroVec = serde_json::from_str(&json_str).unwrap();
633         let bincode_recovered: ZeroTriePerfectHashZeroVec =
634             bincode::deserialize(&bincode_bytes).unwrap();
635 
636         assert_eq!(original.trie, json_recovered.trie);
637         assert_eq!(original.trie, bincode_recovered.trie);
638 
639         assert!(json_recovered.trie.into_store().is_owned());
640         assert!(!bincode_recovered.trie.into_store().is_owned());
641     }
642 }
643