quickjs_rusty/serde/
de.rs

1use std::mem::transmute;
2
3use libquickjs_ng_sys::JSContext;
4use serde::de::{
5    self, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess,
6    Visitor,
7};
8use serde::{forward_to_deserialize_any, Deserialize};
9
10use crate::utils::deserialize_borrowed_str;
11use crate::value::{JsTag, OwnedJsArray, OwnedJsObject, OwnedJsPropertyIterator, OwnedJsValue};
12
13use super::error::{Error, Result};
14
15/// A structure that deserializes JS values into Rust values.
16pub struct Deserializer<'de> {
17    context: *mut JSContext,
18    root: &'de OwnedJsValue,
19    paths: Vec<(OwnedJsValue, u32, Option<OwnedJsPropertyIterator>)>,
20    current: Option<OwnedJsValue>,
21}
22
23impl<'de> Deserializer<'de> {
24    fn from_js(context: *mut JSContext, root: &'de OwnedJsValue) -> Self {
25        Deserializer {
26            context,
27            root,
28            paths: Vec::new(),
29            current: Some(root.clone()),
30        }
31    }
32}
33
34/// Deserialize an instance of type `T` from a JS value.
35pub fn from_js<'a, T>(context: *mut JSContext, value: &'a OwnedJsValue) -> Result<T>
36where
37    T: Deserialize<'a>,
38{
39    let mut deserializer = Deserializer::from_js(context, value);
40    let t = T::deserialize(&mut deserializer)?;
41    Ok(t)
42}
43
44impl<'de> Deserializer<'de> {
45    fn get_current(&self) -> &OwnedJsValue {
46        if let Some(current) = self.current.as_ref() {
47            current
48        } else {
49            self.root
50        }
51    }
52
53    fn next(&mut self) -> Result<Option<()>> {
54        let (current, index, obj_iter) = self.paths.last_mut().expect("current must be Some");
55
56        let next = if current.is_array() {
57            let current = OwnedJsArray::try_from_value(current.clone()).unwrap();
58            let item = current.get_index(*index)?;
59            if item.is_some() {
60                self.current = item;
61                *index += 1;
62                Some(())
63            } else {
64                None
65            }
66        } else if current.is_object() {
67            let obj_iter = obj_iter.as_mut().expect("obj_iter must be Some");
68            if let Some(ret) = obj_iter.next() {
69                self.current = Some(ret?);
70                // index here is useless, but we just keep it for consistency
71                *index += 1;
72                Some(())
73            } else {
74                None
75            }
76        } else {
77            return Err(Error::ExpectedArrayOrObject);
78        };
79
80        if next.is_some() {
81            Ok(next)
82        } else {
83            Ok(None)
84        }
85    }
86
87    fn guard_circular_reference(&self, current: &OwnedJsValue) -> Result<()> {
88        if self.paths.iter().any(|(p, _, _)| p == current) {
89            Err(Error::CircularReference)
90        } else {
91            Ok(())
92        }
93    }
94
95    fn enter_array(&mut self) -> Result<()> {
96        let mut current = self.get_current().clone();
97
98        if current.is_proxy() {
99            current = current.get_proxy_target(true)?;
100        }
101
102        if current.is_array() {
103            self.guard_circular_reference(&current)?;
104            self.paths.push((current, 0, None));
105            Ok(())
106        } else {
107            Err(Error::ExpectedArray)
108        }
109    }
110
111    fn enter_object(&mut self) -> Result<()> {
112        let mut current = self.get_current().clone();
113
114        if current.is_proxy() {
115            current = current.get_proxy_target(true)?;
116        }
117
118        if current.is_object() {
119            let obj = OwnedJsObject::try_from_value(current.clone()).unwrap();
120            self.guard_circular_reference(&current)?;
121            self.paths.push((current, 0, Some(obj.properties_iter()?)));
122            Ok(())
123        } else {
124            Err(Error::ExpectedObject)
125        }
126    }
127
128    fn leave(&mut self) {
129        if let Some((current, _, _)) = self.paths.pop() {
130            self.current = Some(current);
131        }
132    }
133
134    fn parse_string(&mut self) -> Result<String> {
135        let current = self.get_current();
136        if current.is_string() {
137            current.to_string().map_err(|err| err.into())
138        } else {
139            Err(Error::ExpectedString)
140        }
141    }
142
143    fn parse_borrowed_str(&mut self) -> Result<&'de str> {
144        let current = self.get_current();
145        if current.is_string() {
146            let s = deserialize_borrowed_str(self.context, &current.value).unwrap();
147
148            // in this case, 'de is equal to '1
149            // so force transmute lifetime
150            let s = unsafe { transmute(s) };
151
152            Ok(s)
153        } else {
154            Err(Error::ExpectedString)
155        }
156    }
157}
158
159impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
160    type Error = Error;
161
162    // Look at the input data to decide what Serde data model type to
163    // deserialize as. Not all data formats are able to support this operation.
164    // Formats that support `deserialize_any` are known as self-describing.
165    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
166    where
167        V: Visitor<'de>,
168    {
169        let current = self.get_current();
170
171        match current.tag() {
172            JsTag::Undefined => visitor.visit_unit(),
173            JsTag::Int => visitor.visit_i32(current.to_int()?),
174            JsTag::Bool => visitor.visit_bool(current.to_bool()?),
175            JsTag::Null => visitor.visit_unit(),
176            JsTag::String => visitor.visit_string(current.to_string()?),
177            JsTag::Float64 => visitor.visit_f64(current.to_float()?),
178            JsTag::Object => {
179                if current.is_array() {
180                    self.deserialize_seq(visitor)
181                } else {
182                    self.deserialize_map(visitor)
183                }
184            }
185            JsTag::Symbol => visitor.visit_unit(),
186            JsTag::Module => visitor.visit_unit(),
187            JsTag::Exception => self.deserialize_map(visitor),
188            JsTag::CatchOffset => visitor.visit_unit(),
189            JsTag::Uninitialized => visitor.visit_unit(),
190            JsTag::FunctionBytecode => visitor.visit_unit(),
191            #[cfg(feature = "bigint")]
192            JsTag::ShortBigInt => {
193                let bigint = current.to_bigint()?;
194                visitor.visit_i64(bigint.as_i64().ok_or(Error::BigIntOverflow)?)
195            }
196            #[cfg(feature = "bigint")]
197            JsTag::BigInt => {
198                let bigint = current.to_bigint()?;
199                visitor.visit_i64(bigint.as_i64().ok_or(Error::BigIntOverflow)?)
200            } // _ => {
201              //     #[cfg(debug_assertions)]
202              //     {
203              //         println!("current type: {:?}", current.tag());
204              //         println!("current: {}", current.to_json_string(0).unwrap());
205              //     }
206              //     unreachable!("unreachable tag: {:?}", current.tag());
207              // }
208        }
209    }
210
211    forward_to_deserialize_any! {
212        bool
213        i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64
214        string char
215        unit
216        identifier ignored_any
217    }
218
219    fn deserialize_str<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
220    where
221        V: Visitor<'de>,
222    {
223        visitor.visit_borrowed_str(self.parse_borrowed_str()?)
224    }
225
226    fn deserialize_seq<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
227    where
228        V: Visitor<'de>,
229    {
230        self.enter_array()?;
231        let r = visitor.visit_seq(&mut *self);
232        self.leave();
233        r
234    }
235
236    fn deserialize_bytes<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
237    where
238        V: Visitor<'de>,
239    {
240        self.deserialize_byte_buf(visitor)
241    }
242
243    // for some type like &[u8]
244    fn deserialize_byte_buf<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
245    where
246        V: Visitor<'de>,
247    {
248        unimplemented!("borrowed bytes not supported yet")
249        // self.deserialize_seq(visitor)
250    }
251
252    fn deserialize_tuple<V>(
253        self,
254        _len: usize,
255        visitor: V,
256    ) -> std::result::Result<V::Value, Self::Error>
257    where
258        V: Visitor<'de>,
259    {
260        self.deserialize_seq(visitor)
261    }
262
263    fn deserialize_tuple_struct<V>(
264        self,
265        _name: &'static str,
266        _len: usize,
267        visitor: V,
268    ) -> std::result::Result<V::Value, Self::Error>
269    where
270        V: Visitor<'de>,
271    {
272        self.deserialize_seq(visitor)
273    }
274
275    fn deserialize_option<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
276    where
277        V: Visitor<'de>,
278    {
279        if self.get_current().is_null() || self.get_current().is_undefined() {
280            visitor.visit_none()
281        } else {
282            visitor.visit_some(self)
283        }
284    }
285
286    fn deserialize_newtype_struct<V>(
287        self,
288        _name: &'static str,
289        visitor: V,
290    ) -> std::result::Result<V::Value, Self::Error>
291    where
292        V: Visitor<'de>,
293    {
294        visitor.visit_newtype_struct(self)
295    }
296
297    fn deserialize_map<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
298    where
299        V: Visitor<'de>,
300    {
301        self.enter_object()?;
302        let r = visitor.visit_map(&mut *self);
303        self.leave();
304        r
305    }
306
307    // Structs look just like maps in JSON.
308    //
309    // Notice the `fields` parameter - a "struct" in the Serde data model means
310    // that the `Deserialize` implementation is required to know what the fields
311    // are before even looking at the input data. Any key-value pairing in which
312    // the fields cannot be known ahead of time is probably a map.
313    fn deserialize_struct<V>(
314        self,
315        _name: &'static str,
316        _fields: &'static [&'static str],
317        visitor: V,
318    ) -> std::result::Result<V::Value, Self::Error>
319    where
320        V: Visitor<'de>,
321    {
322        self.deserialize_map(visitor)
323    }
324
325    fn deserialize_enum<V>(
326        self,
327        _name: &'static str,
328        _variants: &'static [&'static str],
329        visitor: V,
330    ) -> std::result::Result<V::Value, Self::Error>
331    where
332        V: Visitor<'de>,
333    {
334        if self.get_current().is_object() {
335            // Visit a newtype variant, tuple variant, or struct variant.
336            self.enter_object()?;
337            self.next()?;
338            let r = visitor.visit_enum(Enum::new(self));
339            self.leave();
340            r
341        } else {
342            // Visit a unit variant.
343            visitor.visit_enum(self.parse_string()?.into_deserializer())
344        }
345    }
346
347    fn deserialize_unit_struct<V>(
348        self,
349        _name: &'static str,
350        visitor: V,
351    ) -> std::result::Result<V::Value, Self::Error>
352    where
353        V: Visitor<'de>,
354    {
355        self.deserialize_unit(visitor)
356    }
357}
358
359impl<'de, 'a> SeqAccess<'de> for Deserializer<'de> {
360    type Error = Error;
361
362    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
363    where
364        T: DeserializeSeed<'de>,
365    {
366        if let Some(_) = self.next()? {
367            seed.deserialize(self).map(Some)
368        } else {
369            Ok(None)
370        }
371    }
372}
373
374impl<'de, 'a> MapAccess<'de> for Deserializer<'de> {
375    type Error = Error;
376
377    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
378    where
379        K: DeserializeSeed<'de>,
380    {
381        if let Some(_) = self.next()? {
382            seed.deserialize(self).map(Some)
383        } else {
384            Ok(None)
385        }
386    }
387
388    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
389    where
390        V: DeserializeSeed<'de>,
391    {
392        // It doesn't make a difference whether the colon is parsed at the end
393        // of `next_key_seed` or at the beginning of `next_value_seed`. In this
394        // case the code is a bit simpler having it here.
395        // if self.de.next_char()? != ':' {
396        //     return Err(Error::ExpectedMapColon);
397        // }
398        // Deserialize a map value.
399        self.next()?;
400        seed.deserialize(self)
401    }
402}
403
404struct Enum<'a, 'de: 'a> {
405    de: &'a mut Deserializer<'de>,
406}
407
408impl<'a, 'de> Enum<'a, 'de> {
409    fn new(de: &'a mut Deserializer<'de>) -> Self {
410        Enum { de }
411    }
412}
413
414// `EnumAccess` is provided to the `Visitor` to give it the ability to determine
415// which variant of the enum is supposed to be deserialized.
416//
417// Note that all enum deserialization methods in Serde refer exclusively to the
418// "externally tagged" enum representation.
419impl<'de, 'a> EnumAccess<'de> for Enum<'a, 'de> {
420    type Error = Error;
421    type Variant = Self;
422
423    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
424    where
425        V: DeserializeSeed<'de>,
426    {
427        // The `deserialize_enum` method parsed a `{` character so we are
428        // currently inside of a map. The seed will be deserializing itself from
429        // the key of the map.
430
431        let val = seed.deserialize(&mut *self.de)?;
432        self.de.next()?;
433        // Parse the colon separating map key from value.
434        // if self.de.next_char()? == ':' {
435        Ok((val, self))
436        // } else {
437        //     Err(Error::ExpectedMapColon)
438        // }
439    }
440}
441
442// `VariantAccess` is provided to the `Visitor` to give it the ability to see
443// the content of the single variant that it decided to deserialize.
444impl<'de, 'a> VariantAccess<'de> for Enum<'a, 'de> {
445    type Error = Error;
446
447    // If the `Visitor` expected this variant to be a unit variant, the input
448    // should have been the plain string case handled in `deserialize_enum`.
449    fn unit_variant(self) -> Result<()> {
450        Err(Error::ExpectedString)
451    }
452
453    // Newtype variants are represented in JSON as `{ NAME: VALUE }` so
454    // deserialize the value here.
455    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
456    where
457        T: DeserializeSeed<'de>,
458    {
459        seed.deserialize(self.de)
460    }
461
462    // Tuple variants are represented in JSON as `{ NAME: [DATA...] }` so
463    // deserialize the sequence of data here.
464    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
465    where
466        V: Visitor<'de>,
467    {
468        de::Deserializer::deserialize_seq(self.de, visitor)
469    }
470
471    // Struct variants are represented in JSON as `{ NAME: { K: V, ... } }` so
472    // deserialize the inner map here.
473    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
474    where
475        V: Visitor<'de>,
476    {
477        de::Deserializer::deserialize_map(self.de, visitor)
478    }
479}