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 => 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 } }
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 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 }
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 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 self.enter_object()?;
527 self.next()?;
528 let r = visitor.visit_enum(Enum::new(self));
529 self.leave();
530 r
531 } else {
532 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 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
604impl<'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 let val = seed.deserialize(&mut *self.de)?;
622 self.de.next()?;
623 Ok((val, self))
626 }
630}
631
632impl<'de, 'a> VariantAccess<'de> for Enum<'a, 'de> {
635 type Error = Error;
636
637 fn unit_variant(self) -> Result<()> {
640 Err(Error::ExpectedString)
641 }
642
643 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 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 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}