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 {
30 fn from_wxf<R: Reader<'de>>(r: &mut WxfReader<R>) -> Result<Self, Error> {
32 let tok = r.read_expr_token()?;
33 Self::from_wxf_with_tag(r, tok)
34 }
35
36 fn from_wxf_with_tag<R: Reader<'de>>(
38 r: &mut WxfReader<R>,
39 tok: ExpressionEnum,
40 ) -> Result<Self, Error>;
41}
42
43pub fn err_at(path: impl Into<String>, expected: &'static str, got: String) -> Error {
45 Error::Deserialize {
46 path: path.into(),
47 expected: expected,
48 got: got,
49 }
50}
51
52impl<'de> FromWXF<'de> for &'de str {
61 fn from_wxf_with_tag<R: Reader<'de>>(
62 r: &mut WxfReader<R>,
63 tok: ExpressionEnum,
64 ) -> Result<Self, Error> {
65 if tok != ExpressionEnum::String {
66 return Err(Error::unexpected_token(&["String"], tok));
67 }
68 r.read_str()
69 }
70}
71
72impl<'de> FromWXF<'de> for &'de [u8] {
73 fn from_wxf_with_tag<R: Reader<'de>>(
74 r: &mut WxfReader<R>,
75 tok: ExpressionEnum,
76 ) -> Result<Self, Error> {
77 if tok != ExpressionEnum::ByteArray {
78 return Err(Error::unexpected_token(&["ByteArray"], tok));
79 }
80 r.read_byte_array()
81 }
82}
83
84macro_rules! read_wire {
94 (Integer8, $r:expr) => {
95 $r.read_i8()? as _
96 };
97 (Integer16, $r:expr) => {
98 $r.read_i16()? as _
99 };
100 (Integer32, $r:expr) => {
101 $r.read_i32()? as _
102 };
103 (Integer64, $r:expr) => {
104 $r.read_i64()? as _
105 };
106 (Real64, $r:expr) => {
107 $r.read_f64()? as _
108 };
109}
110
111macro_rules! impl_numeric_from_wxf {
112 ($t:ty, [$($tok:ident),+]) => {
113 impl<'de> FromWXF<'de> for $t {
114 fn from_wxf_with_tag<R: Reader<'de>>(
115 r: &mut WxfReader<R>,
116 tok: ExpressionEnum,
117 ) -> Result<Self, Error> {
118 match tok {
119 $(ExpressionEnum::$tok => Ok(read_wire!($tok, r)),)+
120 other => Err(Error::unexpected_token(
121 &[$(stringify!($tok)),+],
122 other,
123 )),
124 }
125 }
126 }
127 };
128}
129
130impl_numeric_from_wxf!(i8, [Integer8]);
133impl_numeric_from_wxf!(i16, [Integer8, Integer16]);
134impl_numeric_from_wxf!(i32, [Integer8, Integer16, Integer32]);
135impl_numeric_from_wxf!(i64, [Integer8, Integer16, Integer32, Integer64]);
136
137impl_numeric_from_wxf!(f32, [Integer8, Integer16]);
142impl_numeric_from_wxf!(f64, [Integer8, Integer16, Integer32, Real64]);
143
144impl<'de> FromWXF<'de> for bool {
145 fn from_wxf_with_tag<R: Reader<'de>>(
146 r: &mut WxfReader<R>,
147 tok: ExpressionEnum,
148 ) -> Result<Self, Error> {
149 if tok != ExpressionEnum::Symbol {
150 return Err(Error::unexpected_token(&["Symbol"], tok));
151 }
152 match r.read_str()? {
153 "System`True" => Ok(true),
154 "System`False" => Ok(false),
155 other => Err(Error::UnexpectedSymbol {
156 expected: vec!["System`True", "System`False"],
157 got: other.to_owned(),
158 }),
159 }
160 }
161}
162
163impl<'de> FromWXF<'de> for String {
165 fn from_wxf_with_tag<R: Reader<'de>>(
166 r: &mut WxfReader<R>,
167 tok: ExpressionEnum,
168 ) -> Result<Self, Error> {
169 <&str as FromWXF<'de>>::from_wxf_with_tag(r, tok).map(str::to_owned)
170 }
171}
172
173impl<'de> FromWXF<'de> for () {
178 fn from_wxf_with_tag<R: Reader<'de>>(
179 r: &mut WxfReader<R>,
180 tok: ExpressionEnum,
181 ) -> Result<Self, Error> {
182 if tok != ExpressionEnum::Symbol {
183 return Err(Error::unexpected_token(&["Symbol"], tok));
184 }
185 match r.read_str()? {
186 "Null" | "System`Null" => Ok(()),
187 other => Err(Error::UnexpectedSymbol {
188 expected: vec!["Null", "System`Null"],
189 got: other.to_owned(),
190 }),
191 }
192 }
193}
194
195impl<'de, T: FromWXF<'de>> FromWXF<'de> for Option<T> {
199 fn from_wxf_with_tag<R: Reader<'de>>(
200 r: &mut WxfReader<R>,
201 tok: ExpressionEnum,
202 ) -> Result<Self, Error> {
203 let (_n, variant) = crate::strategy::read_enum_header(r, tok)?;
204 match variant.as_str() {
205 "None" => Ok(None),
206 "Some" => {
207 crate::strategy::read_data_header(r, 1)?;
208 Ok(Some(T::from_wxf(r)?))
209 },
210 other => Err(Error::UnexpectedSymbol {
211 expected: vec!["None", "Some"],
212 got: other.to_owned(),
213 }),
214 }
215 }
216}
217
218impl<'de, T: FromWXF<'de>, E: FromWXF<'de>> FromWXF<'de> for Result<T, E> {
219 fn from_wxf_with_tag<R: Reader<'de>>(
220 r: &mut WxfReader<R>,
221 tok: ExpressionEnum,
222 ) -> Result<Self, Error> {
223 let (_n, variant) = crate::strategy::read_enum_header(r, tok)?;
224 match variant.as_str() {
225 "Ok" => {
226 crate::strategy::read_data_header(r, 1)?;
227 Ok(Ok(T::from_wxf(r)?))
228 },
229 "Err" => {
230 crate::strategy::read_data_header(r, 1)?;
231 Ok(Err(E::from_wxf(r)?))
232 },
233 other => Err(Error::UnexpectedSymbol {
234 expected: vec!["Ok", "Err"],
235 got: other.to_owned(),
236 }),
237 }
238 }
239}
240
241impl<'de, K, V> FromWXF<'de> for HashMap<K, V>
242where
243 K: FromWXF<'de> + Eq + std::hash::Hash,
244 V: FromWXF<'de>,
245{
246 fn from_wxf_with_tag<R: Reader<'de>>(
247 r: &mut WxfReader<R>,
248 tok: ExpressionEnum,
249 ) -> Result<Self, Error> {
250 if tok != ExpressionEnum::Association {
251 return Err(Error::unexpected_token(&["Association"], tok));
252 }
253 let n = r.read_varint()?;
254 let mut out = HashMap::with_capacity(n as usize);
255 for _ in 0..n {
256 let _delayed = r.read_rule()?;
257 let k = K::from_wxf(r)?;
258 let v = V::from_wxf(r)?;
259 out.insert(k, v);
260 }
261 Ok(out)
262 }
263}
264
265impl<'de, K, V> FromWXF<'de> for BTreeMap<K, V>
266where
267 K: FromWXF<'de> + Ord,
268 V: FromWXF<'de>,
269{
270 fn from_wxf_with_tag<R: Reader<'de>>(
271 r: &mut WxfReader<R>,
272 tok: ExpressionEnum,
273 ) -> Result<Self, Error> {
274 if tok != ExpressionEnum::Association {
275 return Err(Error::unexpected_token(&["Association"], tok));
276 }
277 let n = r.read_varint()?;
278 let mut out = BTreeMap::new();
279 for _ in 0..n {
280 let _delayed = r.read_rule()?;
281 let k = K::from_wxf(r)?;
282 let v = V::from_wxf(r)?;
283 out.insert(k, v);
284 }
285 Ok(out)
286 }
287}
288
289impl<'de> FromWXF<'de> for Vec<u8> {
295 fn from_wxf_with_tag<R: Reader<'de>>(
296 r: &mut WxfReader<R>,
297 tok: ExpressionEnum,
298 ) -> Result<Self, Error> {
299 <&[u8] as FromWXF<'de>>::from_wxf_with_tag(r, tok).map(<[u8]>::to_vec)
300 }
301}
302
303macro_rules! impl_vec_numeric_from_wxf {
305 ($($t:ty),+ $(,)?) => {
306 $(
307 impl<'de> FromWXF<'de> for Vec<$t> {
308 fn from_wxf_with_tag<R: Reader<'de>>(r: &mut WxfReader<R>, tok: ExpressionEnum) -> Result<Self, Error> {
309 crate::numeric_in::read_vec_with_tag::<$t, R>(r, tok, "")
310 }
311 }
312 )+
313 };
314}
315impl_vec_numeric_from_wxf!(i8, i16, i32, i64, u16, u32, u64, f32, f64);
316
317impl<'de, T: FromWXF<'de> + crate::to_wxf::WxfStruct> FromWXF<'de> for Vec<T> {
319 fn from_wxf_with_tag<R: Reader<'de>>(
320 r: &mut WxfReader<R>,
321 tok: ExpressionEnum,
322 ) -> Result<Self, Error> {
323 if tok != ExpressionEnum::Function {
324 return Err(Error::unexpected_token(&["Function"], tok));
325 }
326 let n = r.read_varint()?;
327 r.skip()?; let mut items = Vec::with_capacity(n as usize);
329 for _ in 0..n {
330 items.push(T::from_wxf(r)?);
331 }
332 Ok(items)
333 }
334}