• 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 super::{VarZeroSlice, VarZeroVec, VarZeroVecFormat};
6 use crate::ule::*;
7 use alloc::boxed::Box;
8 use alloc::vec::Vec;
9 use core::fmt;
10 use core::marker::PhantomData;
11 use serde::de::{self, Deserialize, Deserializer, SeqAccess, Visitor};
12 #[cfg(feature = "serde")]
13 use serde::ser::{Serialize, SerializeSeq, Serializer};
14 
15 struct VarZeroVecVisitor<T: ?Sized, F: VarZeroVecFormat> {
16     #[allow(clippy::type_complexity)] // this is a private marker type, who cares
17     marker: PhantomData<(fn() -> Box<T>, F)>,
18 }
19 
20 impl<T: ?Sized, F: VarZeroVecFormat> Default for VarZeroVecVisitor<T, F> {
default() -> Self21     fn default() -> Self {
22         Self {
23             marker: PhantomData,
24         }
25     }
26 }
27 
28 impl<'de, T, F> Visitor<'de> for VarZeroVecVisitor<T, F>
29 where
30     T: VarULE + ?Sized,
31     Box<T>: Deserialize<'de>,
32     F: VarZeroVecFormat,
33 {
34     type Value = VarZeroVec<'de, T, F>;
35 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result36     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
37         formatter.write_str("a sequence or borrowed buffer of bytes")
38     }
39 
visit_borrowed_bytes<E>(self, bytes: &'de [u8]) -> Result<Self::Value, E> where E: de::Error,40     fn visit_borrowed_bytes<E>(self, bytes: &'de [u8]) -> Result<Self::Value, E>
41     where
42         E: de::Error,
43     {
44         VarZeroVec::parse_bytes(bytes).map_err(de::Error::custom)
45     }
46 
visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> where A: SeqAccess<'de>,47     fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
48     where
49         A: SeqAccess<'de>,
50     {
51         let mut vec: Vec<Box<T>> = if let Some(capacity) = seq.size_hint() {
52             Vec::with_capacity(capacity)
53         } else {
54             Vec::new()
55         };
56         while let Some(value) = seq.next_element::<Box<T>>()? {
57             vec.push(value);
58         }
59         Ok(VarZeroVec::from(&vec))
60     }
61 }
62 
63 /// This impl requires enabling the optional `serde` Cargo feature of the `zerovec` crate
64 impl<'de, 'a, T, F> Deserialize<'de> for VarZeroVec<'a, T, F>
65 where
66     T: VarULE + ?Sized,
67     Box<T>: Deserialize<'de>,
68     F: VarZeroVecFormat,
69     'de: 'a,
70 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,71     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
72     where
73         D: Deserializer<'de>,
74     {
75         let visitor = VarZeroVecVisitor::<T, F>::default();
76         if deserializer.is_human_readable() {
77             deserializer.deserialize_seq(visitor)
78         } else {
79             deserializer.deserialize_bytes(visitor)
80         }
81     }
82 }
83 
84 /// This impl requires enabling the optional `serde` Cargo feature of the `zerovec` crate
85 impl<'de, 'a, T, F> Deserialize<'de> for &'a VarZeroSlice<T, F>
86 where
87     T: VarULE + ?Sized,
88     F: VarZeroVecFormat,
89     'de: 'a,
90 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,91     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
92     where
93         D: Deserializer<'de>,
94     {
95         if deserializer.is_human_readable() {
96             Err(de::Error::custom(
97                 "&VarZeroSlice cannot be deserialized from human-readable formats",
98             ))
99         } else {
100             let bytes = <&[u8]>::deserialize(deserializer)?;
101             VarZeroSlice::<T, F>::parse_bytes(bytes).map_err(de::Error::custom)
102         }
103     }
104 }
105 
106 /// This impl requires enabling the optional `serde` Cargo feature of the `zerovec` crate
107 impl<'de, T, F> Deserialize<'de> for Box<VarZeroSlice<T, F>>
108 where
109     T: VarULE + ?Sized,
110     Box<T>: Deserialize<'de>,
111     F: VarZeroVecFormat,
112 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,113     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
114     where
115         D: Deserializer<'de>,
116     {
117         let deserialized = VarZeroVec::<T, F>::deserialize(deserializer)?;
118         Ok(deserialized.to_boxed())
119     }
120 }
121 
122 /// This impl requires enabling the optional `serde` Cargo feature of the `zerovec` crate
123 #[cfg(feature = "serde")]
124 impl<T, F> Serialize for VarZeroVec<'_, T, F>
125 where
126     T: Serialize + VarULE + ?Sized,
127     F: VarZeroVecFormat,
128 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,129     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
130     where
131         S: Serializer,
132     {
133         if serializer.is_human_readable() {
134             let mut seq = serializer.serialize_seq(Some(self.len()))?;
135             for value in self.iter() {
136                 seq.serialize_element(value)?;
137             }
138             seq.end()
139         } else {
140             serializer.serialize_bytes(self.as_bytes())
141         }
142     }
143 }
144 
145 /// This impl requires enabling the optional `serde` Cargo feature of the `zerovec` crate
146 #[cfg(feature = "serde")]
147 impl<T, F> Serialize for VarZeroSlice<T, F>
148 where
149     T: Serialize + VarULE + ?Sized,
150     F: VarZeroVecFormat,
151 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,152     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
153     where
154         S: Serializer,
155     {
156         self.as_varzerovec().serialize(serializer)
157     }
158 }
159 
160 #[cfg(test)]
161 #[allow(non_camel_case_types)]
162 mod test {
163     use crate::{VarZeroSlice, VarZeroVec};
164 
165     #[derive(serde::Serialize, serde::Deserialize)]
166     struct DeriveTest_VarZeroVec<'data> {
167         #[serde(borrow)]
168         _data: VarZeroVec<'data, str>,
169     }
170 
171     #[derive(serde::Serialize, serde::Deserialize)]
172     struct DeriveTest_VarZeroSlice<'data> {
173         #[serde(borrow)]
174         _data: &'data VarZeroSlice<str>,
175     }
176 
177     #[derive(serde::Serialize, serde::Deserialize)]
178     struct DeriveTest_VarZeroVec_of_VarZeroSlice<'data> {
179         #[serde(borrow)]
180         _data: VarZeroVec<'data, VarZeroSlice<str>>,
181     }
182 
183     // ["foo", "bar", "baz", "dolor", "quux", "lorem ipsum"];
184     const BYTES: &[u8] = &[
185         6, 0, 3, 0, 6, 0, 9, 0, 14, 0, 18, 0, 102, 111, 111, 98, 97, 114, 98, 97, 122, 100, 111,
186         108, 111, 114, 113, 117, 117, 120, 108, 111, 114, 101, 109, 32, 105, 112, 115, 117, 109,
187     ];
188     const JSON_STR: &str = "[\"foo\",\"bar\",\"baz\",\"dolor\",\"quux\",\"lorem ipsum\"]";
189     const BINCODE_BUF: &[u8] = &[
190         41, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 0, 6, 0, 9, 0, 14, 0, 18, 0, 102, 111, 111, 98, 97, 114,
191         98, 97, 122, 100, 111, 108, 111, 114, 113, 117, 117, 120, 108, 111, 114, 101, 109, 32, 105,
192         112, 115, 117, 109,
193     ];
194 
195     // ["w", "ω", "文", "��"]
196     const NONASCII_STR: &[&str] = &["w", "ω", "文", "��"];
197     const NONASCII_BYTES: &[u8] = &[
198         4, 0, 1, 0, 3, 0, 6, 0, 119, 207, 137, 230, 150, 135, 240, 145, 132, 131,
199     ];
200     #[test]
test_serde_json()201     fn test_serde_json() {
202         let zerovec_orig: VarZeroVec<str> = VarZeroVec::parse_bytes(BYTES).expect("parse");
203         let json_str = serde_json::to_string(&zerovec_orig).expect("serialize");
204         assert_eq!(JSON_STR, json_str);
205         // VarZeroVec should deserialize from JSON to either Vec or VarZeroVec
206         let vec_new: Vec<Box<str>> =
207             serde_json::from_str(&json_str).expect("deserialize from buffer to Vec");
208         assert_eq!(zerovec_orig.to_vec(), vec_new);
209         let zerovec_new: VarZeroVec<str> =
210             serde_json::from_str(&json_str).expect("deserialize from buffer to VarZeroVec");
211         assert_eq!(zerovec_orig.to_vec(), zerovec_new.to_vec());
212         assert!(zerovec_new.is_owned());
213     }
214 
215     #[test]
test_serde_bincode()216     fn test_serde_bincode() {
217         let zerovec_orig: VarZeroVec<str> = VarZeroVec::parse_bytes(BYTES).expect("parse");
218         let bincode_buf = bincode::serialize(&zerovec_orig).expect("serialize");
219         assert_eq!(BINCODE_BUF, bincode_buf);
220         let zerovec_new: VarZeroVec<str> =
221             bincode::deserialize(&bincode_buf).expect("deserialize from buffer to VarZeroVec");
222         assert_eq!(zerovec_orig.to_vec(), zerovec_new.to_vec());
223         assert!(!zerovec_new.is_owned());
224     }
225 
226     #[test]
test_vzv_borrowed()227     fn test_vzv_borrowed() {
228         let zerovec_orig: &VarZeroSlice<str> = VarZeroSlice::parse_bytes(BYTES).expect("parse");
229         let bincode_buf = bincode::serialize(&zerovec_orig).expect("serialize");
230         assert_eq!(BINCODE_BUF, bincode_buf);
231         let zerovec_new: &VarZeroSlice<str> =
232             bincode::deserialize(&bincode_buf).expect("deserialize from buffer to VarZeroSlice");
233         assert_eq!(zerovec_orig.to_vec(), zerovec_new.to_vec());
234     }
235 
236     #[test]
test_nonascii_bincode()237     fn test_nonascii_bincode() {
238         let src_vec = NONASCII_STR
239             .iter()
240             .copied()
241             .map(Box::<str>::from)
242             .collect::<Vec<_>>();
243         let mut zerovec: VarZeroVec<str> = VarZeroVec::parse_bytes(NONASCII_BYTES).expect("parse");
244         assert_eq!(zerovec.to_vec(), src_vec);
245         let bincode_buf = bincode::serialize(&zerovec).expect("serialize");
246         let zerovec_result =
247             bincode::deserialize::<VarZeroVec<str>>(&bincode_buf).expect("deserialize");
248         assert_eq!(zerovec_result.to_vec(), src_vec);
249 
250         // try again with owned zerovec
251         zerovec.make_mut();
252         let bincode_buf = bincode::serialize(&zerovec).expect("serialize");
253         let zerovec_result =
254             bincode::deserialize::<VarZeroVec<str>>(&bincode_buf).expect("deserialize");
255         assert_eq!(zerovec_result.to_vec(), src_vec);
256     }
257 }
258