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    fn parse_integer_float(&self) -> Result<f64> {
159        let current = self.get_current();
160        if !current.is_float() {
161            return Err(Error::ExpectedFloat);
162        }
163
164        let value = current.to_float()?;
165
166        #[cfg(feature = "truncate-float-to-int")]
167        {
168            if !value.is_finite() {
169                return Err(Error::ExpectedInteger);
170            }
171
172            Ok(value.trunc())
173        }
174
175        #[cfg(not(feature = "truncate-float-to-int"))]
176        {
177            if !value.is_finite() || value.fract() != 0.0 {
178                return Err(Error::ExpectedInteger);
179            }
180
181            Ok(value)
182        }
183    }
184
185    fn parse_signed_integer(&self) -> Result<i64> {
186        let current = self.get_current();
187
188        if current.is_int() {
189            return Ok(i64::from(current.to_int()?));
190        }
191
192        if current.is_float() {
193            let value = self.parse_integer_float()?;
194            if value < i64::MIN as f64 || value > i64::MAX as f64 {
195                return Err(crate::ValueError::OutOfRange.into());
196            }
197            return Ok(value as i64);
198        }
199
200        #[cfg(feature = "bigint")]
201        if current.is_bigint() {
202            return current.to_bigint()?.as_i64().ok_or(Error::BigIntOverflow);
203        }
204
205        Err(Error::ExpectedInteger)
206    }
207
208    fn parse_unsigned_integer(&self) -> Result<u64> {
209        let current = self.get_current();
210
211        if current.is_int() {
212            let value = current.to_int()?;
213            if value < 0 {
214                return Err(crate::ValueError::OutOfRange.into());
215            }
216            return Ok(value as u64);
217        }
218
219        if current.is_float() {
220            let value = self.parse_integer_float()?;
221            if value < 0.0 || value > u64::MAX as f64 {
222                return Err(crate::ValueError::OutOfRange.into());
223            }
224            return Ok(value as u64);
225        }
226
227        #[cfg(feature = "bigint")]
228        if current.is_bigint() {
229            use num_traits::ToPrimitive;
230
231            return current
232                .to_bigint()?
233                .into_bigint()
234                .to_u64()
235                .ok_or(Error::BigIntOverflow);
236        }
237
238        Err(Error::ExpectedInteger)
239    }
240
241    #[cfg(feature = "bigint")]
242    fn parse_signed_integer_128(&self) -> Result<i128> {
243        let current = self.get_current();
244
245        if current.is_bigint() {
246            use num_traits::ToPrimitive;
247
248            return current
249                .to_bigint()?
250                .into_bigint()
251                .to_i128()
252                .ok_or(Error::BigIntOverflow);
253        }
254
255        if current.is_float() {
256            let value = self.parse_integer_float()?;
257            if value < i128::MIN as f64 || value > i128::MAX as f64 {
258                return Err(crate::ValueError::OutOfRange.into());
259            }
260            return Ok(value as i128);
261        }
262
263        self.parse_signed_integer().map(i128::from)
264    }
265
266    #[cfg(not(feature = "bigint"))]
267    fn parse_signed_integer_128(&self) -> Result<i128> {
268        if self.get_current().is_float() {
269            let value = self.parse_integer_float()?;
270            if value < i128::MIN as f64 || value > i128::MAX as f64 {
271                return Err(crate::ValueError::OutOfRange.into());
272            }
273            return Ok(value as i128);
274        }
275
276        self.parse_signed_integer().map(i128::from)
277    }
278
279    #[cfg(feature = "bigint")]
280    fn parse_unsigned_integer_128(&self) -> Result<u128> {
281        let current = self.get_current();
282
283        if current.is_bigint() {
284            use num_traits::ToPrimitive;
285
286            return current
287                .to_bigint()?
288                .into_bigint()
289                .to_u128()
290                .ok_or(Error::BigIntOverflow);
291        }
292
293        if current.is_float() {
294            let value = self.parse_integer_float()?;
295            if value < 0.0 || value > u128::MAX as f64 {
296                return Err(crate::ValueError::OutOfRange.into());
297            }
298            return Ok(value as u128);
299        }
300
301        self.parse_unsigned_integer().map(u128::from)
302    }
303
304    #[cfg(not(feature = "bigint"))]
305    fn parse_unsigned_integer_128(&self) -> Result<u128> {
306        if self.get_current().is_float() {
307            let value = self.parse_integer_float()?;
308            if value < 0.0 || value > u128::MAX as f64 {
309                return Err(crate::ValueError::OutOfRange.into());
310            }
311            return Ok(value as u128);
312        }
313
314        self.parse_unsigned_integer().map(u128::from)
315    }
316}
317
318macro_rules! deserialize_integer {
319    ($name:ident, $visit:ident, $helper:ident) => {
320        fn $name<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
321        where
322            V: Visitor<'de>,
323        {
324            visitor.$visit(self.$helper()?)
325        }
326    };
327}
328
329impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
330    type Error = Error;
331
332    // Look at the input data to decide what Serde data model type to
333    // deserialize as. Not all data formats are able to support this operation.
334    // Formats that support `deserialize_any` are known as self-describing.
335    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
336    where
337        V: Visitor<'de>,
338    {
339        let raw_current = self.get_current();
340        let current_proxy;
341
342        let current = if raw_current.is_proxy() {
343            current_proxy = Some(raw_current.get_proxy_target(true)?);
344            current_proxy.as_ref().unwrap()
345        } else {
346            raw_current
347        };
348
349        match current.tag() {
350            JsTag::Undefined => visitor.visit_unit(),
351            JsTag::Int => visitor.visit_i32(current.to_int()?),
352            JsTag::Bool => visitor.visit_bool(current.to_bool()?),
353            JsTag::Null => visitor.visit_unit(),
354            JsTag::String => visitor.visit_string(current.to_string()?),
355            JsTag::RopeString => visitor.visit_string(current.to_string()?),
356            JsTag::Float64 => visitor.visit_f64(current.to_float()?),
357            JsTag::Object => {
358                if current.is_array() {
359                    self.deserialize_seq(visitor)
360                } else {
361                    self.deserialize_map(visitor)
362                }
363            }
364            JsTag::Symbol => visitor.visit_unit(),
365            JsTag::Module => visitor.visit_unit(),
366            JsTag::Exception => self.deserialize_map(visitor),
367            JsTag::CatchOffset => visitor.visit_unit(),
368            JsTag::Uninitialized => visitor.visit_unit(),
369            JsTag::FunctionBytecode => visitor.visit_unit(),
370            #[cfg(feature = "bigint")]
371            JsTag::ShortBigInt => {
372                let bigint = current.to_bigint()?;
373                visitor.visit_i64(bigint.as_i64().ok_or(Error::BigIntOverflow)?)
374            }
375            #[cfg(feature = "bigint")]
376            JsTag::BigInt => {
377                let bigint = current.to_bigint()?;
378                visitor.visit_i64(bigint.as_i64().ok_or(Error::BigIntOverflow)?)
379            } // _ => {
380              //     #[cfg(debug_assertions)]
381              //     {
382              //         println!("current type: {:?}", current.tag());
383              //         println!("current: {}", current.to_json_string(0).unwrap());
384              //     }
385              //     unreachable!("unreachable tag: {:?}", current.tag());
386              // }
387        }
388    }
389
390    forward_to_deserialize_any! {
391        bool
392        f32 f64
393        string char
394        unit
395        identifier ignored_any
396    }
397
398    deserialize_integer!(deserialize_i8, visit_i64, parse_signed_integer);
399    deserialize_integer!(deserialize_i16, visit_i64, parse_signed_integer);
400    deserialize_integer!(deserialize_i32, visit_i64, parse_signed_integer);
401    deserialize_integer!(deserialize_i64, visit_i64, parse_signed_integer);
402    deserialize_integer!(deserialize_i128, visit_i128, parse_signed_integer_128);
403    deserialize_integer!(deserialize_u8, visit_u64, parse_unsigned_integer);
404    deserialize_integer!(deserialize_u16, visit_u64, parse_unsigned_integer);
405    deserialize_integer!(deserialize_u32, visit_u64, parse_unsigned_integer);
406    deserialize_integer!(deserialize_u64, visit_u64, parse_unsigned_integer);
407    deserialize_integer!(deserialize_u128, visit_u128, parse_unsigned_integer_128);
408
409    fn deserialize_str<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
410    where
411        V: Visitor<'de>,
412    {
413        visitor.visit_borrowed_str(self.parse_borrowed_str()?)
414    }
415
416    fn deserialize_seq<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
417    where
418        V: Visitor<'de>,
419    {
420        self.enter_array()?;
421        let r = visitor.visit_seq(&mut *self);
422        self.leave();
423        r
424    }
425
426    fn deserialize_bytes<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
427    where
428        V: Visitor<'de>,
429    {
430        self.deserialize_byte_buf(visitor)
431    }
432
433    // for some type like &[u8]
434    fn deserialize_byte_buf<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
435    where
436        V: Visitor<'de>,
437    {
438        unimplemented!("borrowed bytes not supported yet")
439        // self.deserialize_seq(visitor)
440    }
441
442    fn deserialize_tuple<V>(
443        self,
444        _len: usize,
445        visitor: V,
446    ) -> std::result::Result<V::Value, Self::Error>
447    where
448        V: Visitor<'de>,
449    {
450        self.deserialize_seq(visitor)
451    }
452
453    fn deserialize_tuple_struct<V>(
454        self,
455        _name: &'static str,
456        _len: usize,
457        visitor: V,
458    ) -> std::result::Result<V::Value, Self::Error>
459    where
460        V: Visitor<'de>,
461    {
462        self.deserialize_seq(visitor)
463    }
464
465    fn deserialize_option<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
466    where
467        V: Visitor<'de>,
468    {
469        if self.get_current().is_null() || self.get_current().is_undefined() {
470            visitor.visit_none()
471        } else {
472            visitor.visit_some(self)
473        }
474    }
475
476    fn deserialize_newtype_struct<V>(
477        self,
478        _name: &'static str,
479        visitor: V,
480    ) -> std::result::Result<V::Value, Self::Error>
481    where
482        V: Visitor<'de>,
483    {
484        visitor.visit_newtype_struct(self)
485    }
486
487    fn deserialize_map<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
488    where
489        V: Visitor<'de>,
490    {
491        self.enter_object()?;
492        let r = visitor.visit_map(&mut *self);
493        self.leave();
494        r
495    }
496
497    // Structs look just like maps in JSON.
498    //
499    // Notice the `fields` parameter - a "struct" in the Serde data model means
500    // that the `Deserialize` implementation is required to know what the fields
501    // are before even looking at the input data. Any key-value pairing in which
502    // the fields cannot be known ahead of time is probably a map.
503    fn deserialize_struct<V>(
504        self,
505        _name: &'static str,
506        _fields: &'static [&'static str],
507        visitor: V,
508    ) -> std::result::Result<V::Value, Self::Error>
509    where
510        V: Visitor<'de>,
511    {
512        self.deserialize_map(visitor)
513    }
514
515    fn deserialize_enum<V>(
516        self,
517        _name: &'static str,
518        _variants: &'static [&'static str],
519        visitor: V,
520    ) -> std::result::Result<V::Value, Self::Error>
521    where
522        V: Visitor<'de>,
523    {
524        if self.get_current().is_object() {
525            // Visit a newtype variant, tuple variant, or struct variant.
526            self.enter_object()?;
527            self.next()?;
528            let r = visitor.visit_enum(Enum::new(self));
529            self.leave();
530            r
531        } else {
532            // Visit a unit variant.
533            visitor.visit_enum(self.parse_string()?.into_deserializer())
534        }
535    }
536
537    fn deserialize_unit_struct<V>(
538        self,
539        _name: &'static str,
540        visitor: V,
541    ) -> std::result::Result<V::Value, Self::Error>
542    where
543        V: Visitor<'de>,
544    {
545        self.deserialize_unit(visitor)
546    }
547}
548
549impl<'de, 'a> SeqAccess<'de> for Deserializer<'de> {
550    type Error = Error;
551
552    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
553    where
554        T: DeserializeSeed<'de>,
555    {
556        if let Some(_) = self.next()? {
557            seed.deserialize(self).map(Some)
558        } else {
559            Ok(None)
560        }
561    }
562}
563
564impl<'de, 'a> MapAccess<'de> for Deserializer<'de> {
565    type Error = Error;
566
567    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
568    where
569        K: DeserializeSeed<'de>,
570    {
571        if let Some(_) = self.next()? {
572            seed.deserialize(self).map(Some)
573        } else {
574            Ok(None)
575        }
576    }
577
578    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
579    where
580        V: DeserializeSeed<'de>,
581    {
582        // It doesn't make a difference whether the colon is parsed at the end
583        // of `next_key_seed` or at the beginning of `next_value_seed`. In this
584        // case the code is a bit simpler having it here.
585        // if self.de.next_char()? != ':' {
586        //     return Err(Error::ExpectedMapColon);
587        // }
588        // Deserialize a map value.
589        self.next()?;
590        seed.deserialize(self)
591    }
592}
593
594struct Enum<'a, 'de: 'a> {
595    de: &'a mut Deserializer<'de>,
596}
597
598impl<'a, 'de> Enum<'a, 'de> {
599    fn new(de: &'a mut Deserializer<'de>) -> Self {
600        Enum { de }
601    }
602}
603
604// `EnumAccess` is provided to the `Visitor` to give it the ability to determine
605// which variant of the enum is supposed to be deserialized.
606//
607// Note that all enum deserialization methods in Serde refer exclusively to the
608// "externally tagged" enum representation.
609impl<'de, 'a> EnumAccess<'de> for Enum<'a, 'de> {
610    type Error = Error;
611    type Variant = Self;
612
613    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
614    where
615        V: DeserializeSeed<'de>,
616    {
617        // The `deserialize_enum` method parsed a `{` character so we are
618        // currently inside of a map. The seed will be deserializing itself from
619        // the key of the map.
620
621        let val = seed.deserialize(&mut *self.de)?;
622        self.de.next()?;
623        // Parse the colon separating map key from value.
624        // if self.de.next_char()? == ':' {
625        Ok((val, self))
626        // } else {
627        //     Err(Error::ExpectedMapColon)
628        // }
629    }
630}
631
632// `VariantAccess` is provided to the `Visitor` to give it the ability to see
633// the content of the single variant that it decided to deserialize.
634impl<'de, 'a> VariantAccess<'de> for Enum<'a, 'de> {
635    type Error = Error;
636
637    // If the `Visitor` expected this variant to be a unit variant, the input
638    // should have been the plain string case handled in `deserialize_enum`.
639    fn unit_variant(self) -> Result<()> {
640        Err(Error::ExpectedString)
641    }
642
643    // Newtype variants are represented in JSON as `{ NAME: VALUE }` so
644    // deserialize the value here.
645    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
646    where
647        T: DeserializeSeed<'de>,
648    {
649        seed.deserialize(self.de)
650    }
651
652    // Tuple variants are represented in JSON as `{ NAME: [DATA...] }` so
653    // deserialize the sequence of data here.
654    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
655    where
656        V: Visitor<'de>,
657    {
658        de::Deserializer::deserialize_seq(self.de, visitor)
659    }
660
661    // Struct variants are represented in JSON as `{ NAME: { K: V, ... } }` so
662    // deserialize the inner map here.
663    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
664    where
665        V: Visitor<'de>,
666    {
667        de::Deserializer::deserialize_map(self.de, visitor)
668    }
669}