1use alloc::string::{String, ToString as _};
2use alloc::vec::Vec;
3
4use rquickjs::{
5 Exception, Filter, Function, Null, Object, String as JSString, Value,
6 atom::PredefinedAtom,
7 function::This,
8 object::ObjectIter,
9 qjs::{
10 JS_GetClassID, JS_GetProperty, JS_GetPropertyUint32, JS_TAG_EXCEPTION,
11 JS_VALUE_GET_NORM_TAG,
12 },
13};
14use serde::{
15 de::{self, IntoDeserializer},
16 forward_to_deserialize_any,
17};
18
19use crate::err::{Error, Result};
20use crate::utils::{as_key, to_string_lossy};
21use crate::{MAX_SAFE_INTEGER, MIN_SAFE_INTEGER};
22
23enum ClassId {
27 Number = 4,
28 String = 5,
29 Bool = 6,
30 BigInt = 35,
31}
32
33pub struct Deserializer<'js> {
54 value: Value<'js>,
55 strict: bool,
57 map_key: bool,
58 current_kv: Option<(Value<'js>, Value<'js>)>,
59 stack: Vec<Value<'js>>,
61}
62
63impl<'js> Deserializer<'js> {
64 pub fn new(value: Value<'js>) -> Self {
65 Self::from(value)
66 }
67
68 pub fn with_strict(self) -> Self {
69 Self {
70 strict: true,
71 ..self
72 }
73 }
74}
75
76impl<'de> From<Value<'de>> for Deserializer<'de> {
77 fn from(value: Value<'de>) -> Self {
78 Self {
79 value,
80 strict: false,
81 map_key: false,
82 current_kv: None,
83 stack: Vec::with_capacity(100),
86 }
87 }
88}
89
90impl<'js> Deserializer<'js> {
91 fn deserialize_number<'de, V>(&mut self, visitor: V) -> Result<V::Value>
92 where
93 V: de::Visitor<'de>,
94 {
95 if let Some(i) = self.value.as_int() {
96 return visitor.visit_i32(i);
97 }
98
99 if let Some(f64_representation) = self.value.as_float() {
100 let is_positive = f64_representation.is_sign_positive();
101 let safe_integer_range = (MIN_SAFE_INTEGER as f64)..=(MAX_SAFE_INTEGER as f64);
102 let whole = (f64_representation % 1.0) == 0.0;
103
104 if whole && is_positive && f64_representation <= u32::MAX as f64 {
105 return visitor.visit_u32(f64_representation as u32);
106 }
107
108 if whole && safe_integer_range.contains(&f64_representation) {
109 let x = f64_representation as i64;
110 return visitor.visit_i64(x);
111 }
112
113 return visitor.visit_f64(f64_representation);
114 }
115
116 Err(Error::new(Exception::throw_type(
117 self.value.ctx(),
118 "Unsupported number type",
119 )))
120 }
121
122 fn pop_visited(&mut self) -> Result<Value<'js>> {
124 let v = self
125 .stack
126 .pop()
127 .ok_or_else(|| Error::new("No entries found in the deserializer stack"))?;
128 Ok(v)
129 }
130
131 fn check_cycles(&self) -> Result<()> {
135 for val in self.stack.iter().rev() {
136 if self.value.eq(val) {
137 return Err(Error::new(Exception::throw_type(
138 val.ctx(),
139 "circular dependency",
140 )));
141 }
142 }
143 Ok(())
144 }
145}
146
147impl<'de> de::Deserializer<'de> for &mut Deserializer<'de> {
148 type Error = Error;
149
150 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
151 where
152 V: de::Visitor<'de>,
153 {
154 if self.value.is_number() {
155 return self.deserialize_number(visitor);
156 }
157
158 if get_class_id(&self.value) == ClassId::Number as u32 {
159 let value_of = get_valueof(&self.value);
160 if let Some(f) = value_of {
161 let v = f.call((This(self.value.clone()),)).map_err(Error::new)?;
162 self.value = v;
163 return self.deserialize_number(visitor);
164 }
165 }
166
167 if let Some(b) = self.value.as_bool() {
168 return visitor.visit_bool(b);
169 }
170
171 if get_class_id(&self.value) == ClassId::Bool as u32 {
172 let value_of = get_valueof(&self.value);
173 if let Some(f) = value_of {
174 let v = f.call((This(self.value.clone()),)).map_err(Error::new)?;
175 return visitor.visit_bool(v);
176 }
177 }
178
179 if self.value.is_null() || self.value.is_undefined() {
180 return visitor.visit_unit();
181 }
182
183 if get_class_id(&self.value) == ClassId::String as u32 {
184 let value_of = get_to_string(&self.value);
185 if let Some(f) = value_of {
186 let v = f.call(((This(self.value.clone())),)).map_err(Error::new)?;
187 self.value = v;
188 }
189 }
190
191 if self.value.is_string() {
192 if self.map_key {
193 self.map_key = false;
194 let key = as_key(&self.value)?;
195 return visitor.visit_str(&key);
196 } else {
197 let val = self
198 .value
199 .as_string()
200 .map(|s| {
201 s.to_string()
202 .unwrap_or_else(|e| to_string_lossy(self.value.ctx(), s, e))
203 })
204 .unwrap();
205 return visitor.visit_str(&val);
206 }
207 }
208
209 if is_array_or_proxy_of_array(&self.value)
210 && let Some(seq) = self.value.as_object()
211 {
212 let seq_access = SeqAccess::new(self, seq.clone())?;
213 return visitor.visit_seq(seq_access);
214 }
215
216 if self.value.is_object() {
217 ensure_supported(&self.value)?;
218
219 if let Some(f) = get_to_json(&self.value) {
220 let v: Value = f.call((This(self.value.clone()),)).map_err(Error::new)?;
221
222 if v.is_undefined() {
223 self.value = Value::new_undefined(v.ctx().clone());
224 } else {
225 self.value = v;
226 }
227 return self.deserialize_any(visitor);
228 }
229
230 let map_access = MapAccess::new(self, self.value.clone().into_object().unwrap())?;
231 let result = visitor.visit_map(map_access);
232 return result;
233 }
234
235 if get_class_id(&self.value) == ClassId::BigInt as u32 || self.value.is_big_int() {
236 if let Some(f) = get_to_json(&self.value) {
237 let v: Value = f.call((This(self.value.clone()),)).map_err(Error::new)?;
238 self.value = v;
239 return self.deserialize_any(visitor);
240 }
241
242 if let Some(f) = get_to_string(&self.value)
243 && !self.strict
244 {
245 let v: Value = f.call((This(self.value.clone()),)).map_err(Error::new)?;
246 self.value = v;
247 return self.deserialize_any(visitor);
248 }
249 }
250
251 Err(Error::new(Exception::throw_type(
252 self.value.ctx(),
253 "Unsupported type",
254 )))
255 }
256
257 fn is_human_readable(&self) -> bool {
258 false
259 }
260
261 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
262 where
263 V: de::Visitor<'de>,
264 {
265 if self.value.is_null() || self.value.is_undefined() {
266 visitor.visit_none()
267 } else {
268 visitor.visit_some(self)
269 }
270 }
271
272 fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
273 where
274 V: de::Visitor<'de>,
275 {
276 visitor.visit_newtype_struct(self)
277 }
278
279 fn deserialize_enum<V>(
280 self,
281 _name: &'static str,
282 _variants: &'static [&'static str],
283 visitor: V,
284 ) -> Result<V::Value>
285 where
286 V: de::Visitor<'de>,
287 {
288 if get_class_id(&self.value) == ClassId::String as u32
289 && let Some(f) = get_to_string(&self.value)
290 {
291 let v = f.call((This(self.value.clone()),)).map_err(Error::new)?;
292 self.value = v;
293 }
294
295 if let Some(obj) = self.value.as_object() {
296 let (variant, value): (String, Value<'de>) = obj
297 .props::<String, Value>()
298 .next()
299 .ok_or_else(|| Error::new("expected enum object with one key"))?
300 .map_err(Error::new)?;
301
302 visitor.visit_enum(EnumAccessImpl {
303 variant,
304 value: Some(value.clone()),
305 })
306 } else if let Some(s) = self.value.as_string() {
307 let s = s
309 .to_string()
310 .unwrap_or_else(|e| to_string_lossy(self.value.ctx(), s, e));
311
312 visitor.visit_enum(EnumAccessImpl {
313 variant: s,
314 value: None,
315 })
316 } else {
317 Err(Error::new("expected a string or object for enum"))
318 }
319 }
320
321 forward_to_deserialize_any! {
322 bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string
323 bytes byte_buf unit unit_struct seq tuple
324 tuple_struct map struct identifier ignored_any
325 }
326}
327
328struct MapAccess<'a, 'de: 'a> {
330 de: &'a mut Deserializer<'de>,
332 properties: ObjectIter<'de, Value<'de>, Value<'de>>,
334 obj: Object<'de>,
336}
337
338impl<'a, 'de> MapAccess<'a, 'de> {
339 fn new(de: &'a mut Deserializer<'de>, obj: Object<'de>) -> Result<Self> {
340 let filter = Filter::new().enum_only().string();
341 let properties: ObjectIter<'_, _, Value<'_>> =
342 obj.own_props::<Value<'_>, Value<'_>>(filter);
343
344 let val = obj.clone().into_value();
345 de.stack.push(val.clone());
346
347 Ok(Self {
348 de,
349 properties,
350 obj,
351 })
352 }
353
354 fn pop(&mut self) -> Result<()> {
357 let v = self.de.pop_visited()?;
358 if v != self.obj.clone().into_value() {
359 return Err(Error::new(
360 "Popped a mismatched value. Expected the top level sequence value",
361 ));
362 }
363
364 Ok(())
365 }
366}
367
368impl<'de> de::MapAccess<'de> for MapAccess<'_, 'de> {
369 type Error = Error;
370
371 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
372 where
373 K: de::DeserializeSeed<'de>,
374 {
375 loop {
376 if let Some(kv) = self.properties.next() {
377 let (k, v) = kv.map_err(Error::new)?;
378
379 let to_json = get_to_json(&v);
380 let v = if let Some(f) = to_json {
381 f.call((This(v.clone()), k.clone())).map_err(Error::new)?
382 } else {
383 v
384 };
385
386 if !ensure_supported(&v)? || k.is_symbol() {
389 continue;
390 }
391
392 let class_id = get_class_id(&v);
393
394 if class_id == ClassId::Bool as u32 || class_id == ClassId::Number as u32 {
395 let value_of = get_valueof(&v);
396 if let Some(f) = value_of {
397 let v = f.call((This(v.clone()),)).map_err(Error::new)?;
398 self.de.current_kv = Some((k.clone(), v));
399 }
400 } else if class_id == ClassId::String as u32 {
401 let to_string = get_to_string(&v);
402 if let Some(f) = to_string {
403 let v = f.call((This(v.clone()),)).map_err(Error::new)?;
404 self.de.current_kv = Some((k.clone(), v));
405 }
406 } else {
407 self.de.current_kv = Some((k.clone(), v));
408 }
409 self.de.value = k;
410 self.de.map_key = true;
411
412 return seed.deserialize(&mut *self.de).map(Some);
413 } else {
414 self.pop()?;
415 return Ok(None);
416 }
417 }
418 }
419
420 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
421 where
422 V: de::DeserializeSeed<'de>,
423 {
424 self.de.value = self.de.current_kv.clone().unwrap().1;
425 self.de.check_cycles()?;
426 seed.deserialize(&mut *self.de)
427 }
428}
429
430struct SeqAccess<'a, 'de: 'a> {
432 de: &'a mut Deserializer<'de>,
434 seq: Object<'de>,
438 length: usize,
440 index: usize,
442}
443
444impl<'a, 'de: 'a> SeqAccess<'a, 'de> {
445 fn new(de: &'a mut Deserializer<'de>, seq: Object<'de>) -> Result<Self> {
448 de.stack.push(seq.clone().into_value());
449
450 let value: Value = seq.get(PredefinedAtom::Length).map_err(Error::new)?;
455 let length: usize = if let Some(n) = value.as_number() {
456 n as usize
457 } else {
458 let value_of: Function = value
459 .as_object()
460 .expect("length to be an object")
461 .get(PredefinedAtom::ValueOf)
462 .map_err(Error::new)?;
463 value_of.call(()).map_err(Error::new)?
464 };
465
466 Ok(Self {
467 de,
468 seq,
469 length,
470 index: 0,
471 })
472 }
473
474 fn pop(&mut self) -> Result<()> {
477 let v = self.de.pop_visited()?;
478 if v != self.seq.clone().into_value() {
479 return Err(Error::new(
480 "Popped a mismatched value. Expected the top level sequence value",
481 ));
482 }
483
484 Ok(())
485 }
486}
487
488impl<'de> de::SeqAccess<'de> for SeqAccess<'_, 'de> {
489 type Error = Error;
490
491 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
492 where
493 T: de::DeserializeSeed<'de>,
494 {
495 if self.index < self.length {
496 let el = get_index(&self.seq, self.index).map_err(Error::new)?;
497 let to_json = get_to_json(&el);
498
499 if let Some(f) = to_json {
500 let index_value = JSString::from_str(el.ctx().clone(), &self.index.to_string());
501 self.de.value = f
502 .call((This(el.clone()), index_value))
503 .map_err(Error::new)?;
504 } else if ensure_supported(&el)? {
505 self.de.value = el
506 } else {
507 self.de.value = Null.into_value(self.seq.ctx().clone())
508 }
509 self.index += 1;
510 self.de.check_cycles()?;
513 seed.deserialize(&mut *self.de).map(Some)
514 } else {
515 self.pop()?;
517 Ok(None)
518 }
519 }
520}
521
522pub(crate) fn get_to_json<'a>(value: &Value<'a>) -> Option<Function<'a>> {
524 get_function(value, PredefinedAtom::ToJSON)
525}
526
527fn get_valueof<'a>(value: &Value<'a>) -> Option<Function<'a>> {
529 get_function(value, PredefinedAtom::ValueOf)
530}
531
532fn get_to_string<'a>(value: &Value<'a>) -> Option<Function<'a>> {
534 get_function(value, PredefinedAtom::ToString)
535}
536
537fn get_function<'a>(value: &Value<'a>, atom: PredefinedAtom) -> Option<Function<'a>> {
538 let f = unsafe { JS_GetProperty(value.ctx().as_raw().as_ptr(), value.as_raw(), atom as u32) };
539 let f = unsafe { Value::from_raw(value.ctx().clone(), f) };
540 if f.is_function()
541 && let Some(f) = f.into_function()
542 {
543 Some(f)
544 } else {
545 None
546 }
547}
548
549fn get_class_id(v: &Value) -> u32 {
551 unsafe { JS_GetClassID(v.as_raw()) }
552}
553
554fn ensure_supported(value: &Value<'_>) -> Result<bool> {
556 let class_id = get_class_id(value);
557 if class_id == (ClassId::Bool as u32) || class_id == (ClassId::Number as u32) {
558 return Ok(true);
559 }
560
561 if class_id == ClassId::BigInt as u32 {
562 return Err(Error::new(Exception::throw_type(
563 value.ctx(),
564 "BigInt not supported",
565 )));
566 }
567
568 Ok(!matches!(
569 value.type_of(),
570 rquickjs::Type::Undefined
571 | rquickjs::Type::Symbol
572 | rquickjs::Type::Function
573 | rquickjs::Type::Uninitialized
574 | rquickjs::Type::Constructor
575 ))
576}
577
578fn is_array_or_proxy_of_array(val: &Value) -> bool {
579 if val.is_array() {
580 return true;
581 }
582 let mut val = val.clone();
583 loop {
584 let Some(proxy) = val.into_proxy() else {
585 return false;
586 };
587 let Ok(target) = proxy.target() else {
588 return false;
589 };
590 val = target.into_value();
591 if val.is_array() {
592 return true;
593 }
594 }
595}
596
597fn get_index<'a>(obj: &Object<'a>, idx: usize) -> rquickjs::Result<Value<'a>> {
598 unsafe {
599 let ctx = obj.ctx();
600 let val = JS_GetPropertyUint32(ctx.as_raw().as_ptr(), obj.as_raw(), idx as _);
601 if JS_VALUE_GET_NORM_TAG(val) == JS_TAG_EXCEPTION {
602 return Err(rquickjs::Error::Exception);
603 }
604 Ok(Value::from_raw(ctx.clone(), val))
605 }
606}
607
608struct EnumAccessImpl<'de> {
610 variant: String,
612 value: Option<Value<'de>>,
614}
615
616impl<'de> de::EnumAccess<'de> for EnumAccessImpl<'de> {
617 type Error = Error;
618 type Variant = VariantAccessImpl<'de>;
619
620 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
621 where
622 V: de::DeserializeSeed<'de>,
623 {
624 let val = seed.deserialize(self.variant.into_deserializer())?;
625 Ok((val, VariantAccessImpl { value: self.value }))
626 }
627}
628
629struct VariantAccessImpl<'de> {
630 value: Option<Value<'de>>,
631}
632
633impl<'de> de::VariantAccess<'de> for VariantAccessImpl<'de> {
634 type Error = Error;
635
636 fn unit_variant(self) -> Result<()> {
637 match self.value {
638 None => Ok(()),
639 Some(_) => Err(Error::new("expected unit variant")),
640 }
641 }
642
643 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
644 where
645 T: de::DeserializeSeed<'de>,
646 {
647 let value = self
648 .value
649 .ok_or_else(|| Error::new("expected value for newtype variant"))?;
650
651 seed.deserialize(&mut Deserializer::from(value))
652 }
653
654 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
655 where
656 V: de::Visitor<'de>,
657 {
658 let value = self
659 .value
660 .ok_or_else(|| Error::new("expected tuple variant"))?;
661
662 de::Deserializer::deserialize_seq(&mut Deserializer::from(value), visitor)
663 }
664
665 fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
666 where
667 V: de::Visitor<'de>,
668 {
669 let value = self
670 .value
671 .ok_or_else(|| Error::new("expected struct variant"))?;
672
673 de::Deserializer::deserialize_map(&mut Deserializer::from(value), visitor)
674 }
675}
676
677#[cfg(test)]
678mod tests {
679 use std::collections::BTreeMap;
680
681 use rquickjs::Value;
682 use serde::de::DeserializeOwned;
683 use serde::{Deserialize, Serialize};
684
685 use super::Deserializer as ValueDeserializer;
686 use crate::test::Runtime;
687 use crate::{MAX_SAFE_INTEGER, from_value, to_value};
688
689 fn deserialize_value<T>(v: Value<'_>) -> T
690 where
691 T: DeserializeOwned,
692 {
693 let ctx = v.ctx().clone();
694 let mut deserializer = ValueDeserializer::from(v);
695 match T::deserialize(&mut deserializer) {
696 Ok(val) => val,
697 Err(e) => panic!("{}", e.catch(&ctx)),
698 }
699 }
700
701 #[test]
702 fn test_null() {
703 let rt = Runtime::default();
704 rt.context().with(|cx| {
705 let val = Value::new_null(cx);
706 deserialize_value::<()>(val);
707 });
708 }
709
710 #[test]
711 fn test_undefined() {
712 let rt = Runtime::default();
713 rt.context().with(|cx| {
714 let val = Value::new_undefined(cx);
715 deserialize_value::<()>(val);
716 });
717 }
718
719 #[test]
720 fn test_nan() {
721 let rt = Runtime::default();
722 rt.context().with(|cx| {
723 let val = Value::new_float(cx, f64::NAN);
724 let actual = deserialize_value::<f64>(val);
725 assert!(actual.is_nan());
726 });
727 }
728
729 #[test]
730 fn test_infinity() {
731 let rt = Runtime::default();
732
733 rt.context().with(|cx| {
734 let val = Value::new_float(cx, f64::INFINITY);
735 let actual = deserialize_value::<f64>(val);
736 assert!(actual.is_infinite() && actual.is_sign_positive());
737 });
738 }
739
740 #[test]
741 fn test_negative_infinity() {
742 let rt = Runtime::default();
743 rt.context().with(|cx| {
744 let val = Value::new_float(cx, f64::NEG_INFINITY);
745 let actual = deserialize_value::<f64>(val);
746 assert!(actual.is_infinite() && actual.is_sign_negative());
747 })
748 }
749
750 #[test]
751 fn test_map_always_converts_keys_to_string() {
752 let rt = Runtime::default();
753 rt.context().with(|c| {
756 c.eval::<Value<'_>, _>("var a = {1337: 42};").unwrap();
757 let val = c.globals().get("a").unwrap();
758 let actual = deserialize_value::<BTreeMap<String, i32>>(val);
759
760 assert_eq!(42, *actual.get("1337").unwrap())
761 });
762 }
763
764 #[test]
765 fn test_u64_bounds() {
766 let rt = Runtime::default();
767 rt.context().with(|c| {
768 let max = u64::MAX;
769 let val = Value::new_number(c.clone(), max as f64);
770 let actual = deserialize_value::<f64>(val);
771 assert_eq!(max as f64, actual);
772
773 let min = u64::MIN;
774 let val = Value::new_number(c.clone(), min as f64);
775 let actual = deserialize_value::<f64>(val);
776 assert_eq!(min as f64, actual);
777 });
778 }
779
780 #[test]
781 fn test_i64_bounds() {
782 let rt = Runtime::default();
783
784 rt.context().with(|c| {
785 let max = i64::MAX;
786 let val = Value::new_number(c.clone(), max as _);
787 let actual = deserialize_value::<f64>(val);
788 assert_eq!(max as f64, actual);
789
790 let min = i64::MIN;
791 let val = Value::new_number(c.clone(), min as _);
792 let actual = deserialize_value::<f64>(val);
793 assert_eq!(min as f64, actual);
794 });
795 }
796
797 #[test]
798 fn test_float_to_integer_conversion() {
799 let rt = Runtime::default();
800
801 rt.context().with(|c| {
802 let expected = MAX_SAFE_INTEGER - 1;
803 let val = Value::new_float(c.clone(), expected as _);
804 let actual = deserialize_value::<i64>(val);
805 assert_eq!(expected, actual);
806
807 let expected = MAX_SAFE_INTEGER + 1;
808 let val = Value::new_float(c.clone(), expected as _);
809 let actual = deserialize_value::<f64>(val);
810 assert_eq!(expected as f64, actual);
811 });
812 }
813
814 #[test]
815 fn test_u32_upper_bound() {
816 let rt = Runtime::default();
817
818 rt.context().with(|c| {
819 let expected = u32::MAX;
820 let val = Value::new_number(c, expected as _);
821 let actual = deserialize_value::<u32>(val);
822 assert_eq!(expected, actual);
823 });
824 }
825
826 #[test]
827 fn test_u32_lower_bound() {
828 let rt = Runtime::default();
829
830 rt.context().with(|cx| {
831 let expected = i32::MAX as u32 + 1;
832 let val = Value::new_number(cx, expected as _);
833 let actual = deserialize_value::<u32>(val);
834 assert_eq!(expected, actual);
835 });
836 }
837
838 #[test]
839 fn test_array() {
840 let rt = Runtime::default();
841 rt.context().with(|cx| {
842 cx.eval::<Value<'_>, _>("var a = [1, 2, 3];").unwrap();
843 let v = cx.globals().get("a").unwrap();
844
845 let val = deserialize_value::<Vec<u8>>(v);
846
847 assert_eq!(vec![1, 2, 3], val);
848 });
849 }
850
851 #[test]
852 fn test_array_proxy() {
853 let rt = Runtime::default();
854 rt.context().with(|cx| {
855 cx.eval::<Value<'_>, _>(
856 r#"
857 var arr = [1, 2, 3];
858 var a = new Proxy(arr, {});
859 "#,
860 )
861 .unwrap();
862 let v = cx.globals().get("a").unwrap();
863 let val = deserialize_value::<Vec<u8>>(v);
864 assert_eq!(vec![1, 2, 3], val);
865 });
866 }
867
868 #[test]
869 fn test_non_json_object_values_are_dropped() {
870 let rt = Runtime::default();
871 rt.context().with(|cx| {
872 cx.eval::<Value<'_>, _>(
873 r#"
874 var unitialized;
875 var a = {
876 a: undefined,
877 b: function() {},
878 c: Symbol(),
879 d: () => {},
880 e: unitialized,
881 };"#,
882 )
883 .unwrap();
884 let v = cx.globals().get("a").unwrap();
885
886 let val = deserialize_value::<BTreeMap<String, ()>>(v);
887 assert_eq!(BTreeMap::new(), val);
888 });
889 }
890
891 #[test]
892 fn test_non_json_array_values_are_null() {
893 let rt = Runtime::default();
894 rt.context().with(|cx| {
895 cx.eval::<Value<'_>, _>(
896 r#"
897 var unitialized;
898 var a = [
899 undefined,
900 function() {},
901 Symbol(),
902 () => {},
903 unitialized,
904 ];"#,
905 )
906 .unwrap();
907 let v = cx.globals().get("a").unwrap();
908
909 let val = deserialize_value::<Vec<Option<()>>>(v);
910 assert_eq!(vec![None; 5], val);
911 });
912 }
913
914 #[test]
915 fn test_enum_unit() {
916 let rt = Runtime::default();
917
918 #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
919 enum Test {
920 One,
921 Two,
922 Three,
923 }
924
925 rt.context().with(|cx| {
926 let left = Test::Two;
927 let value = to_value(cx, left).unwrap();
928 let right: Test = from_value(value).unwrap();
929 assert_eq!(left, right);
930 });
931 }
932
933 #[test]
934 fn test_enum_newtype() {
935 let rt = Runtime::default();
936
937 #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
938 enum Test {
939 One(i32),
940 Two(i32),
941 }
942
943 rt.context().with(|cx| {
944 let left = Test::One(6);
945 let value = to_value(cx, left).unwrap();
946 let right: Test = from_value(value).unwrap();
947 assert_eq!(left, right);
948 });
949 }
950
951 #[test]
952 fn test_enum_struct() {
953 let rt = Runtime::default();
954
955 #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
956 enum Test {
957 One { a: i32 },
958 Two(i32),
959 }
960
961 rt.context().with(|cx| {
962 let left = Test::One { a: 6 };
963 let value = to_value(cx, left).unwrap();
964 let right: Test = from_value(value).unwrap();
965 assert_eq!(left, right);
966 });
967 }
968
969 #[test]
970 fn test_enum_tuple() {
971 let rt = Runtime::default();
972
973 #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
974 enum Test {
975 One(i32, i32),
976 }
977
978 rt.context().with(|cx| {
979 let left = Test::One(1, 2);
980 let value = to_value(cx, left).unwrap();
981 let right: Test = from_value(value).unwrap();
982 assert_eq!(left, right);
983 });
984 }
985
986 #[test]
987 fn test_short_bigint() {
988 let rt = Runtime::default();
989 rt.context().with(|cx| {
990 cx.eval::<Value<'_>, _>("var a = BigInt(1);").unwrap();
991 let v = cx.globals().get("a").unwrap();
992 let val = deserialize_value::<String>(v);
993 assert_eq!(val, "1");
994 });
995 }
996
997 #[test]
998 fn test_bigint() {
999 let rt = Runtime::default();
1000 rt.context().with(|cx| {
1001 cx.eval::<Value<'_>, _>(
1002 r#"
1003 const left = 12345678901234567890n;
1004 const right = 98765432109876543210n;
1005 var a = left * right;
1006 "#,
1007 )
1008 .unwrap();
1009 let v = cx.globals().get("a").unwrap();
1010 let val = deserialize_value::<String>(v);
1011 assert_eq!(val, "1219326311370217952237463801111263526900");
1012 });
1013 }
1014}