1use std::collections::{BTreeMap, HashMap};
14
15use crate::constants::ExpressionEnum;
16use crate::reader::Reader;
17use crate::wxf::reader::WxfReader;
18use crate::Error;
19
20pub trait FromWXF<'de>: Sized {
73 fn from_wxf<R: Reader<'de>>(r: &mut WxfReader<R>) -> Result<Self, Error> {
75 let tok = r.read_expr_token()?;
76 Self::from_wxf_with_tag(r, tok)
77 }
78
79 #[doc(hidden)]
80 fn from_wxf_with_tag<R: Reader<'de>>(
81 r: &mut WxfReader<R>,
82 tok: ExpressionEnum,
83 ) -> Result<Self, Error>;
84}
85
86pub fn err_at(path: impl Into<String>, expected: &'static str, got: String) -> Error {
88 Error::Deserialize {
89 path: path.into(),
90 expected: expected,
91 got: got,
92 }
93}
94
95impl<'de> FromWXF<'de> for &'de str {
104 fn from_wxf_with_tag<R: Reader<'de>>(
105 r: &mut WxfReader<R>,
106 tok: ExpressionEnum,
107 ) -> Result<Self, Error> {
108 if tok != ExpressionEnum::String {
109 return Err(Error::unexpected_token(&["String"], tok));
110 }
111 r.read_str()
112 }
113}
114
115impl<'de> FromWXF<'de> for &'de [u8] {
116 fn from_wxf_with_tag<R: Reader<'de>>(
117 r: &mut WxfReader<R>,
118 tok: ExpressionEnum,
119 ) -> Result<Self, Error> {
120 if tok != ExpressionEnum::ByteArray {
121 return Err(Error::unexpected_token(&["ByteArray"], tok));
122 }
123 r.read_byte_array()
124 }
125}
126
127macro_rules! read_wire {
137 (Integer8, $r:expr) => {
138 $r.read_i8()? as _
139 };
140 (Integer16, $r:expr) => {
141 $r.read_i16()? as _
142 };
143 (Integer32, $r:expr) => {
144 $r.read_i32()? as _
145 };
146 (Integer64, $r:expr) => {
147 $r.read_i64()? as _
148 };
149 (Real64, $r:expr) => {
150 $r.read_f64()? as _
151 };
152}
153
154macro_rules! impl_numeric_from_wxf {
155 ($t:ty, [$($tok:ident),+]) => {
156 impl<'de> FromWXF<'de> for $t {
157 fn from_wxf_with_tag<R: Reader<'de>>(
158 r: &mut WxfReader<R>,
159 tok: ExpressionEnum,
160 ) -> Result<Self, Error> {
161 match tok {
162 $(ExpressionEnum::$tok => Ok(read_wire!($tok, r)),)+
163 other => Err(Error::unexpected_token(
164 &[$(stringify!($tok)),+],
165 other,
166 )),
167 }
168 }
169 }
170 };
171}
172
173impl_numeric_from_wxf!(i8, [Integer8]);
176impl_numeric_from_wxf!(i16, [Integer8, Integer16]);
177impl_numeric_from_wxf!(i32, [Integer8, Integer16, Integer32]);
178impl_numeric_from_wxf!(i64, [Integer8, Integer16, Integer32, Integer64]);
179
180impl_numeric_from_wxf!(f32, [Integer8, Integer16]);
185impl_numeric_from_wxf!(f64, [Integer8, Integer16, Integer32, Real64]);
186
187impl<'de> FromWXF<'de> for bool {
188 fn from_wxf_with_tag<R: Reader<'de>>(
189 r: &mut WxfReader<R>,
190 tok: ExpressionEnum,
191 ) -> Result<Self, Error> {
192 if tok != ExpressionEnum::Symbol {
193 return Err(Error::unexpected_token(&["Symbol"], tok));
194 }
195 match r.read_str()? {
196 "System`True" => Ok(true),
197 "System`False" => Ok(false),
198 other => Err(Error::UnexpectedSymbol {
199 expected: vec!["System`True", "System`False"],
200 got: other.to_owned(),
201 }),
202 }
203 }
204}
205
206impl<'de> FromWXF<'de> for String {
208 fn from_wxf_with_tag<R: Reader<'de>>(
209 r: &mut WxfReader<R>,
210 tok: ExpressionEnum,
211 ) -> Result<Self, Error> {
212 <&str as FromWXF<'de>>::from_wxf_with_tag(r, tok).map(str::to_owned)
213 }
214}
215
216impl<'de> FromWXF<'de> for () {
221 fn from_wxf_with_tag<R: Reader<'de>>(
222 r: &mut WxfReader<R>,
223 tok: ExpressionEnum,
224 ) -> Result<Self, Error> {
225 if tok != ExpressionEnum::Symbol {
226 return Err(Error::unexpected_token(&["Symbol"], tok));
227 }
228 match r.read_str()? {
229 "Null" | "System`Null" => Ok(()),
230 other => Err(Error::UnexpectedSymbol {
231 expected: vec!["Null", "System`Null"],
232 got: other.to_owned(),
233 }),
234 }
235 }
236}
237
238impl<'de, T: FromWXF<'de>> FromWXF<'de> for Option<T> {
242 fn from_wxf_with_tag<R: Reader<'de>>(
243 r: &mut WxfReader<R>,
244 tok: ExpressionEnum,
245 ) -> Result<Self, Error> {
246 let (_n, variant) = crate::strategy::read_enum_header(r, tok)?;
247 match variant.as_str() {
248 "None" => Ok(None),
249 "Some" => Ok(Some(T::from_wxf(r)?)),
250 other => Err(Error::UnexpectedSymbol {
251 expected: vec!["None", "Some"],
252 got: other.to_owned(),
253 }),
254 }
255 }
256}
257
258impl<'de, T: FromWXF<'de>, E: FromWXF<'de>> FromWXF<'de> for Result<T, E> {
259 fn from_wxf_with_tag<R: Reader<'de>>(
260 r: &mut WxfReader<R>,
261 tok: ExpressionEnum,
262 ) -> Result<Self, Error> {
263 let (_n, variant) = crate::strategy::read_enum_header(r, tok)?;
264 match variant.as_str() {
265 "Ok" => Ok(Ok(T::from_wxf(r)?)),
266 "Err" => Ok(Err(E::from_wxf(r)?)),
267 other => Err(Error::UnexpectedSymbol {
268 expected: vec!["Ok", "Err"],
269 got: other.to_owned(),
270 }),
271 }
272 }
273}
274
275impl<'de, K, V> FromWXF<'de> for HashMap<K, V>
276where
277 K: FromWXF<'de> + Eq + std::hash::Hash,
278 V: FromWXF<'de>,
279{
280 fn from_wxf_with_tag<R: Reader<'de>>(
281 r: &mut WxfReader<R>,
282 tok: ExpressionEnum,
283 ) -> Result<Self, Error> {
284 if tok != ExpressionEnum::Association {
285 return Err(Error::unexpected_token(&["Association"], tok));
286 }
287 let n = r.read_varint()?;
288 let mut out = HashMap::with_capacity(crate::capped_capacity(n as usize));
289 for _ in 0..n {
290 let _delayed = r.read_rule()?;
291 let k = K::from_wxf(r)?;
292 let v = V::from_wxf(r)?;
293 out.insert(k, v);
294 }
295 Ok(out)
296 }
297}
298
299impl<'de, K, V> FromWXF<'de> for BTreeMap<K, V>
300where
301 K: FromWXF<'de> + Ord,
302 V: FromWXF<'de>,
303{
304 fn from_wxf_with_tag<R: Reader<'de>>(
305 r: &mut WxfReader<R>,
306 tok: ExpressionEnum,
307 ) -> Result<Self, Error> {
308 if tok != ExpressionEnum::Association {
309 return Err(Error::unexpected_token(&["Association"], tok));
310 }
311 let n = r.read_varint()?;
312 let mut out = BTreeMap::new();
313 for _ in 0..n {
314 let _delayed = r.read_rule()?;
315 let k = K::from_wxf(r)?;
316 let v = V::from_wxf(r)?;
317 out.insert(k, v);
318 }
319 Ok(out)
320 }
321}
322
323impl<'de> FromWXF<'de> for Vec<u8> {
329 fn from_wxf_with_tag<R: Reader<'de>>(
330 r: &mut WxfReader<R>,
331 tok: ExpressionEnum,
332 ) -> Result<Self, Error> {
333 <&[u8] as FromWXF<'de>>::from_wxf_with_tag(r, tok).map(<[u8]>::to_vec)
334 }
335}
336
337macro_rules! impl_vec_numeric_from_wxf {
339 ($($t:ty),+ $(,)?) => {
340 $(
341 impl<'de> FromWXF<'de> for Vec<$t> {
342 fn from_wxf_with_tag<R: Reader<'de>>(r: &mut WxfReader<R>, tok: ExpressionEnum) -> Result<Self, Error> {
343 crate::numeric_in::read_vec_with_tag::<$t, R>(r, tok, "")
344 }
345 }
346 )+
347 };
348}
349impl_vec_numeric_from_wxf!(i8, i16, i32, i64, u16, u32, u64, f32, f64);
350
351impl<'de, T: FromWXF<'de> + crate::to_wxf::WxfStruct> FromWXF<'de> for Vec<T> {
353 fn from_wxf_with_tag<R: Reader<'de>>(
354 r: &mut WxfReader<R>,
355 tok: ExpressionEnum,
356 ) -> Result<Self, Error> {
357 if tok != ExpressionEnum::Function {
358 return Err(Error::unexpected_token(&["Function"], tok));
359 }
360 let n = r.read_varint()?;
361 r.skip()?; let mut items = Vec::with_capacity(crate::capped_capacity(n as usize));
363 for _ in 0..n {
364 items.push(T::from_wxf(r)?);
365 }
366 Ok(items)
367 }
368}