Skip to main content

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::RopeString => visitor.visit_string(current.to_string()?),
178            JsTag::Float64 => visitor.visit_f64(current.to_float()?),
179            JsTag::Object => {
180                if current.is_array() {
181                    self.deserialize_seq(visitor)
182                } else {
183                    self.deserialize_map(visitor)
184                }
185            }
186            JsTag::Symbol => visitor.visit_unit(),
187            JsTag::Module => visitor.visit_unit(),
188            JsTag::Exception => self.deserialize_map(visitor),
189            JsTag::CatchOffset => visitor.visit_unit(),
190            JsTag::Uninitialized => visitor.visit_unit(),
191            JsTag::FunctionBytecode => visitor.visit_unit(),
192            #[cfg(feature = "bigint")]
193            JsTag::ShortBigInt => {
194                let bigint = current.to_bigint()?;
195                visitor.visit_i64(bigint.as_i64().ok_or(Error::BigIntOverflow)?)
196            }
197            #[cfg(feature = "bigint")]
198            JsTag::BigInt => {
199                let bigint = current.to_bigint()?;
200                visitor.visit_i64(bigint.as_i64().ok_or(Error::BigIntOverflow)?)
201            } // _ => {
202              //     #[cfg(debug_assertions)]
203              //     {
204              //         println!("current type: {:?}", current.tag());
205              //         println!("current: {}", current.to_json_string(0).unwrap());
206              //     }
207              //     unreachable!("unreachable tag: {:?}", current.tag());
208              // }
209        }
210    }
211
212    forward_to_deserialize_any! {
213        bool
214        i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64
215        string char
216        unit
217        identifier ignored_any
218    }
219
220    fn deserialize_str<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
221    where
222        V: Visitor<'de>,
223    {
224        visitor.visit_borrowed_str(self.parse_borrowed_str()?)
225    }
226
227    fn deserialize_seq<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
228    where
229        V: Visitor<'de>,
230    {
231        self.enter_array()?;
232        let r = visitor.visit_seq(&mut *self);
233        self.leave();
234        r
235    }
236
237    fn deserialize_bytes<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
238    where
239        V: Visitor<'de>,
240    {
241        self.deserialize_byte_buf(visitor)
242    }
243
244    // for some type like &[u8]
245    fn deserialize_byte_buf<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
246    where
247        V: Visitor<'de>,
248    {
249        unimplemented!("borrowed bytes not supported yet")
250        // self.deserialize_seq(visitor)
251    }
252
253    fn deserialize_tuple<V>(
254        self,
255        _len: usize,
256        visitor: V,
257    ) -> std::result::Result<V::Value, Self::Error>
258    where
259        V: Visitor<'de>,
260    {
261        self.deserialize_seq(visitor)
262    }
263
264    fn deserialize_tuple_struct<V>(
265        self,
266        _name: &'static str,
267        _len: usize,
268        visitor: V,
269    ) -> std::result::Result<V::Value, Self::Error>
270    where
271        V: Visitor<'de>,
272    {
273        self.deserialize_seq(visitor)
274    }
275
276    fn deserialize_option<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
277    where
278        V: Visitor<'de>,
279    {
280        if self.get_current().is_null() || self.get_current().is_undefined() {
281            visitor.visit_none()
282        } else {
283            visitor.visit_some(self)
284        }
285    }
286
287    fn deserialize_newtype_struct<V>(
288        self,
289        _name: &'static str,
290        visitor: V,
291    ) -> std::result::Result<V::Value, Self::Error>
292    where
293        V: Visitor<'de>,
294    {
295        visitor.visit_newtype_struct(self)
296    }
297
298    fn deserialize_map<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
299    where
300        V: Visitor<'de>,
301    {
302        self.enter_object()?;
303        let r = visitor.visit_map(&mut *self);
304        self.leave();
305        r
306    }
307
308    // Structs look just like maps in JSON.
309    //
310    // Notice the `fields` parameter - a "struct" in the Serde data model means
311    // that the `Deserialize` implementation is required to know what the fields
312    // are before even looking at the input data. Any key-value pairing in which
313    // the fields cannot be known ahead of time is probably a map.
314    fn deserialize_struct<V>(
315        self,
316        _name: &'static str,
317        _fields: &'static [&'static str],
318        visitor: V,
319    ) -> std::result::Result<V::Value, Self::Error>
320    where
321        V: Visitor<'de>,
322    {
323        self.deserialize_map(visitor)
324    }
325
326    fn deserialize_enum<V>(
327        self,
328        _name: &'static str,
329        _variants: &'static [&'static str],
330        visitor: V,
331    ) -> std::result::Result<V::Value, Self::Error>
332    where
333        V: Visitor<'de>,
334    {
335        if self.get_current().is_object() {
336            // Visit a newtype variant, tuple variant, or struct variant.
337            self.enter_object()?;
338            self.next()?;
339            let r = visitor.visit_enum(Enum::new(self));
340            self.leave();
341            r
342        } else {
343            // Visit a unit variant.
344            visitor.visit_enum(self.parse_string()?.into_deserializer())
345        }
346    }
347
348    fn deserialize_unit_struct<V>(
349        self,
350        _name: &'static str,
351        visitor: V,
352    ) -> std::result::Result<V::Value, Self::Error>
353    where
354        V: Visitor<'de>,
355    {
356        self.deserialize_unit(visitor)
357    }
358}
359
360impl<'de, 'a> SeqAccess<'de> for Deserializer<'de> {
361    type Error = Error;
362
363    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
364    where
365        T: DeserializeSeed<'de>,
366    {
367        if let Some(_) = self.next()? {
368            seed.deserialize(self).map(Some)
369        } else {
370            Ok(None)
371        }
372    }
373}
374
375impl<'de, 'a> MapAccess<'de> for Deserializer<'de> {
376    type Error = Error;
377
378    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
379    where
380        K: DeserializeSeed<'de>,
381    {
382        if let Some(_) = self.next()? {
383            seed.deserialize(self).map(Some)
384        } else {
385            Ok(None)
386        }
387    }
388
389    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
390    where
391        V: DeserializeSeed<'de>,
392    {
393        // It doesn't make a difference whether the colon is parsed at the end
394        // of `next_key_seed` or at the beginning of `next_value_seed`. In this
395        // case the code is a bit simpler having it here.
396        // if self.de.next_char()? != ':' {
397        //     return Err(Error::ExpectedMapColon);
398        // }
399        // Deserialize a map value.
400        self.next()?;
401        seed.deserialize(self)
402    }
403}
404
405struct Enum<'a, 'de: 'a> {
406    de: &'a mut Deserializer<'de>,
407}
408
409impl<'a, 'de> Enum<'a, 'de> {
410    fn new(de: &'a mut Deserializer<'de>) -> Self {
411        Enum { de }
412    }
413}
414
415// `EnumAccess` is provided to the `Visitor` to give it the ability to determine
416// which variant of the enum is supposed to be deserialized.
417//
418// Note that all enum deserialization methods in Serde refer exclusively to the
419// "externally tagged" enum representation.
420impl<'de, 'a> EnumAccess<'de> for Enum<'a, 'de> {
421    type Error = Error;
422    type Variant = Self;
423
424    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
425    where
426        V: DeserializeSeed<'de>,
427    {
428        // The `deserialize_enum` method parsed a `{` character so we are
429        // currently inside of a map. The seed will be deserializing itself from
430        // the key of the map.
431
432        let val = seed.deserialize(&mut *self.de)?;
433        self.de.next()?;
434        // Parse the colon separating map key from value.
435        // if self.de.next_char()? == ':' {
436        Ok((val, self))
437        // } else {
438        //     Err(Error::ExpectedMapColon)
439        // }
440    }
441}
442
443// `VariantAccess` is provided to the `Visitor` to give it the ability to see
444// the content of the single variant that it decided to deserialize.
445impl<'de, 'a> VariantAccess<'de> for Enum<'a, 'de> {
446    type Error = Error;
447
448    // If the `Visitor` expected this variant to be a unit variant, the input
449    // should have been the plain string case handled in `deserialize_enum`.
450    fn unit_variant(self) -> Result<()> {
451        Err(Error::ExpectedString)
452    }
453
454    // Newtype variants are represented in JSON as `{ NAME: VALUE }` so
455    // deserialize the value here.
456    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
457    where
458        T: DeserializeSeed<'de>,
459    {
460        seed.deserialize(self.de)
461    }
462
463    // Tuple variants are represented in JSON as `{ NAME: [DATA...] }` so
464    // deserialize the sequence of data here.
465    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
466    where
467        V: Visitor<'de>,
468    {
469        de::Deserializer::deserialize_seq(self.de, visitor)
470    }
471
472    // Struct variants are represented in JSON as `{ NAME: { K: V, ... } }` so
473    // deserialize the inner map here.
474    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
475    where
476        V: Visitor<'de>,
477    {
478        de::Deserializer::deserialize_map(self.de, visitor)
479    }
480}