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
15pub 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
34pub 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 += 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(¤t)?;
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(¤t)?;
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, ¤t.value).unwrap();
147
148 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 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 => {
357 let value = current.to_float()?;
358 if value.is_finite() && value.fract() == 0.0 {
359 if value >= 0.0 && value < u64::MAX as f64 {
361 visitor.visit_u64(value as u64)
362 } else if value >= i64::MIN as f64 && value < 0.0 {
363 visitor.visit_i64(value as i64)
364 } else {
365 visitor.visit_f64(value)
366 }
367 } else {
368 visitor.visit_f64(value)
369 }
370 }
371 JsTag::Object => {
372 if current.is_array() {
373 self.deserialize_seq(visitor)
374 } else {
375 self.deserialize_map(visitor)
376 }
377 }
378 JsTag::Symbol => visitor.visit_unit(),
379 JsTag::Module => visitor.visit_unit(),
380 JsTag::Exception => self.deserialize_map(visitor),
381 JsTag::CatchOffset => visitor.visit_unit(),
382 JsTag::Uninitialized => visitor.visit_unit(),
383 JsTag::FunctionBytecode => visitor.visit_unit(),
384 #[cfg(feature = "bigint")]
385 JsTag::ShortBigInt => {
386 let bigint = current.to_bigint()?;
387 visitor.visit_i64(bigint.as_i64().ok_or(Error::BigIntOverflow)?)
388 }
389 #[cfg(feature = "bigint")]
390 JsTag::BigInt => {
391 let bigint = current.to_bigint()?;
392 visitor.visit_i64(bigint.as_i64().ok_or(Error::BigIntOverflow)?)
393 } }
402 }
403
404 forward_to_deserialize_any! {
405 bool
406 f32 f64
407 string char
408 unit
409 identifier ignored_any
410 }
411
412 deserialize_integer!(deserialize_i8, visit_i64, parse_signed_integer);
413 deserialize_integer!(deserialize_i16, visit_i64, parse_signed_integer);
414 deserialize_integer!(deserialize_i32, visit_i64, parse_signed_integer);
415 deserialize_integer!(deserialize_i64, visit_i64, parse_signed_integer);
416 deserialize_integer!(deserialize_i128, visit_i128, parse_signed_integer_128);
417 deserialize_integer!(deserialize_u8, visit_u64, parse_unsigned_integer);
418 deserialize_integer!(deserialize_u16, visit_u64, parse_unsigned_integer);
419 deserialize_integer!(deserialize_u32, visit_u64, parse_unsigned_integer);
420 deserialize_integer!(deserialize_u64, visit_u64, parse_unsigned_integer);
421 deserialize_integer!(deserialize_u128, visit_u128, parse_unsigned_integer_128);
422
423 fn deserialize_str<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
424 where
425 V: Visitor<'de>,
426 {
427 visitor.visit_borrowed_str(self.parse_borrowed_str()?)
428 }
429
430 fn deserialize_seq<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
431 where
432 V: Visitor<'de>,
433 {
434 self.enter_array()?;
435 let r = visitor.visit_seq(&mut *self);
436 self.leave();
437 r
438 }
439
440 fn deserialize_bytes<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
441 where
442 V: Visitor<'de>,
443 {
444 self.deserialize_byte_buf(visitor)
445 }
446
447 fn deserialize_byte_buf<V>(self, _: V) -> std::result::Result<V::Value, Self::Error>
449 where
450 V: Visitor<'de>,
451 {
452 unimplemented!("borrowed bytes not supported yet")
453 }
455
456 fn deserialize_tuple<V>(
457 self,
458 _len: usize,
459 visitor: V,
460 ) -> std::result::Result<V::Value, Self::Error>
461 where
462 V: Visitor<'de>,
463 {
464 self.deserialize_seq(visitor)
465 }
466
467 fn deserialize_tuple_struct<V>(
468 self,
469 _name: &'static str,
470 _len: usize,
471 visitor: V,
472 ) -> std::result::Result<V::Value, Self::Error>
473 where
474 V: Visitor<'de>,
475 {
476 self.deserialize_seq(visitor)
477 }
478
479 fn deserialize_option<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
480 where
481 V: Visitor<'de>,
482 {
483 if self.get_current().is_null() || self.get_current().is_undefined() {
484 visitor.visit_none()
485 } else {
486 visitor.visit_some(self)
487 }
488 }
489
490 fn deserialize_newtype_struct<V>(
491 self,
492 _name: &'static str,
493 visitor: V,
494 ) -> std::result::Result<V::Value, Self::Error>
495 where
496 V: Visitor<'de>,
497 {
498 visitor.visit_newtype_struct(self)
499 }
500
501 fn deserialize_map<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
502 where
503 V: Visitor<'de>,
504 {
505 self.enter_object()?;
506 let r = visitor.visit_map(&mut *self);
507 self.leave();
508 r
509 }
510
511 fn deserialize_struct<V>(
518 self,
519 _name: &'static str,
520 _fields: &'static [&'static str],
521 visitor: V,
522 ) -> std::result::Result<V::Value, Self::Error>
523 where
524 V: Visitor<'de>,
525 {
526 self.deserialize_map(visitor)
527 }
528
529 fn deserialize_enum<V>(
530 self,
531 _name: &'static str,
532 _variants: &'static [&'static str],
533 visitor: V,
534 ) -> std::result::Result<V::Value, Self::Error>
535 where
536 V: Visitor<'de>,
537 {
538 if self.get_current().is_object() {
539 self.enter_object()?;
541 self.next()?;
542 let r = visitor.visit_enum(Enum::new(self));
543 self.leave();
544 r
545 } else {
546 visitor.visit_enum(self.parse_string()?.into_deserializer())
548 }
549 }
550
551 fn deserialize_unit_struct<V>(
552 self,
553 _name: &'static str,
554 visitor: V,
555 ) -> std::result::Result<V::Value, Self::Error>
556 where
557 V: Visitor<'de>,
558 {
559 self.deserialize_unit(visitor)
560 }
561}
562
563impl<'de, 'a> SeqAccess<'de> for Deserializer<'de> {
564 type Error = Error;
565
566 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
567 where
568 T: DeserializeSeed<'de>,
569 {
570 if let Some(_) = self.next()? {
571 seed.deserialize(self).map(Some)
572 } else {
573 Ok(None)
574 }
575 }
576}
577
578impl<'de, 'a> MapAccess<'de> for Deserializer<'de> {
579 type Error = Error;
580
581 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
582 where
583 K: DeserializeSeed<'de>,
584 {
585 if let Some(_) = self.next()? {
586 seed.deserialize(self).map(Some)
587 } else {
588 Ok(None)
589 }
590 }
591
592 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
593 where
594 V: DeserializeSeed<'de>,
595 {
596 self.next()?;
604 seed.deserialize(self)
605 }
606}
607
608struct Enum<'a, 'de: 'a> {
609 de: &'a mut Deserializer<'de>,
610}
611
612impl<'a, 'de> Enum<'a, 'de> {
613 fn new(de: &'a mut Deserializer<'de>) -> Self {
614 Enum { de }
615 }
616}
617
618impl<'de, 'a> EnumAccess<'de> for Enum<'a, 'de> {
624 type Error = Error;
625 type Variant = Self;
626
627 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
628 where
629 V: DeserializeSeed<'de>,
630 {
631 let val = seed.deserialize(&mut *self.de)?;
636 self.de.next()?;
637 Ok((val, self))
640 }
644}
645
646impl<'de, 'a> VariantAccess<'de> for Enum<'a, 'de> {
649 type Error = Error;
650
651 fn unit_variant(self) -> Result<()> {
654 Err(Error::ExpectedString)
655 }
656
657 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
660 where
661 T: DeserializeSeed<'de>,
662 {
663 seed.deserialize(self.de)
664 }
665
666 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
669 where
670 V: Visitor<'de>,
671 {
672 de::Deserializer::deserialize_seq(self.de, visitor)
673 }
674
675 fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
678 where
679 V: Visitor<'de>,
680 {
681 de::Deserializer::deserialize_map(self.de, visitor)
682 }
683}