1use js_sys::{Array, ArrayBuffer, JsString, Map, Number, Object, Symbol, Uint8Array};
2use serde::de::value::{MapDeserializer, SeqDeserializer};
3use serde::de::{self, IntoDeserializer};
4use std::convert::TryFrom;
5use wasm_bindgen::convert::IntoWasmAbi;
6use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
7
8use crate::preserve::PRESERVED_VALUE_MAGIC;
9use crate::{static_str_to_js, Error, ObjectExt, Result};
10
11struct SeqAccess {
13 iter: js_sys::IntoIter,
14}
15
16impl<'de> de::SeqAccess<'de> for SeqAccess {
17 type Error = Error;
18
19 fn next_element_seed<T: de::DeserializeSeed<'de>>(
20 &mut self,
21 seed: T,
22 ) -> Result<Option<T::Value>> {
23 Ok(match self.iter.next().transpose()? {
24 Some(value) => Some(seed.deserialize(Deserializer::from(value))?),
25 None => None,
26 })
27 }
28}
29
30struct MapAccess {
32 iter: js_sys::IntoIter,
33 next_value: Option<Deserializer>,
34}
35
36impl MapAccess {
37 const fn new(iter: js_sys::IntoIter) -> Self {
38 Self {
39 iter,
40 next_value: None,
41 }
42 }
43}
44
45impl<'de> de::MapAccess<'de> for MapAccess {
46 type Error = Error;
47
48 fn next_key_seed<K: de::DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>> {
49 debug_assert!(self.next_value.is_none());
50
51 Ok(match self.iter.next().transpose()? {
52 Some(pair) => {
53 let (key, value) = convert_pair(pair);
54 self.next_value = Some(value);
55 Some(seed.deserialize(key)?)
56 }
57 None => None,
58 })
59 }
60
61 fn next_value_seed<V: de::DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value> {
62 seed.deserialize(self.next_value.take().unwrap_throw())
63 }
64}
65
66struct ObjectAccess {
67 obj: ObjectExt,
68 fields: std::slice::Iter<'static, &'static str>,
69 next_value: Option<Deserializer>,
70}
71
72impl ObjectAccess {
73 fn new(obj: ObjectExt, fields: &'static [&'static str]) -> Self {
74 Self {
75 obj,
76 fields: fields.iter(),
77 next_value: None,
78 }
79 }
80}
81
82fn str_deserializer(s: &str) -> de::value::StrDeserializer<Error> {
83 de::IntoDeserializer::into_deserializer(s)
84}
85
86impl<'de> de::MapAccess<'de> for ObjectAccess {
87 type Error = Error;
88
89 fn next_key_seed<K: de::DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>> {
90 debug_assert!(self.next_value.is_none());
91
92 for field in &mut self.fields {
93 let js_field = static_str_to_js(field);
94 let next_value = self.obj.get_with_ref_key(&js_field);
95 let is_missing_field = next_value.is_undefined() && !js_field.js_in(&self.obj);
98 if !is_missing_field {
99 self.next_value = Some(Deserializer::from(next_value));
100 return Ok(Some(seed.deserialize(str_deserializer(field))?));
101 }
102 }
103
104 Ok(None)
105 }
106
107 fn next_value_seed<V: de::DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value> {
108 seed.deserialize(self.next_value.take().unwrap_throw())
109 }
110}
111
112enum PreservedValueAccess {
113 OnMagic(JsValue),
114 OnValue(JsValue),
115 Done,
116}
117
118impl<'de> de::SeqAccess<'de> for PreservedValueAccess {
119 type Error = Error;
120
121 fn next_element_seed<T: de::DeserializeSeed<'de>>(
122 &mut self,
123 seed: T,
124 ) -> Result<Option<T::Value>> {
125 let this = std::mem::replace(self, Self::Done);
127 match this {
128 Self::OnMagic(value) => {
129 *self = Self::OnValue(value);
130 seed.deserialize(str_deserializer(PRESERVED_VALUE_MAGIC))
131 .map(Some)
132 }
133 Self::OnValue(value) => seed
134 .deserialize(Deserializer {
135 value: JsValue::from(value.into_abi()),
136 })
137 .map(Some),
138 Self::Done => Ok(None),
139 }
140 }
141}
142
143struct EnumAccess {
145 tag: Deserializer,
146 payload: Deserializer,
147}
148
149impl<'de> de::EnumAccess<'de> for EnumAccess {
150 type Error = Error;
151 type Variant = Deserializer;
152
153 fn variant_seed<V: de::DeserializeSeed<'de>>(
154 self,
155 seed: V,
156 ) -> Result<(V::Value, Self::Variant)> {
157 Ok((seed.deserialize(self.tag)?, self.payload))
158 }
159}
160
161pub struct Deserializer {
163 value: JsValue,
164}
165
166impl From<JsValue> for Deserializer {
167 fn from(value: JsValue) -> Self {
168 Self { value }
169 }
170}
171
172impl<'de> IntoDeserializer<'de, Error> for Deserializer {
175 type Deserializer = Self;
176
177 fn into_deserializer(self) -> Self::Deserializer {
178 self
179 }
180}
181
182fn convert_pair(pair: JsValue) -> (Deserializer, Deserializer) {
184 let pair = pair.unchecked_into::<Array>();
185 (pair.get(0).into(), pair.get(1).into())
186}
187
188impl Deserializer {
189 fn as_object_entries(&self) -> Option<Array> {
190 if self.value.is_object() {
191 Some(Object::entries(self.value.unchecked_ref()))
192 } else {
193 None
194 }
195 }
196
197 fn is_nullish(&self) -> bool {
198 self.value.loose_eq(&JsValue::NULL)
199 }
200
201 fn as_bytes(&self) -> Option<Vec<u8>> {
202 let temp;
203
204 let v = if let Some(v) = self.value.dyn_ref::<Uint8Array>() {
205 v
206 } else if let Some(v) = self.value.dyn_ref::<ArrayBuffer>() {
207 temp = Uint8Array::new(v);
208 &temp
209 } else {
210 return None;
211 };
212
213 Some(v.to_vec())
214 }
215
216 #[cold]
217 fn invalid_type_(&self, visitor: &dyn de::Expected) -> Error {
218 let string;
219 let bytes;
220
221 let unexpected = if self.is_nullish() {
222 de::Unexpected::Unit
223 } else if let Some(v) = self.value.as_bool() {
224 de::Unexpected::Bool(v)
225 } else if let Some(v) = self.value.as_f64() {
226 de::Unexpected::Float(v)
227 } else if let Some(v) = self.value.as_string() {
228 string = v;
229 de::Unexpected::Str(&string)
230 } else if let Some(v) = self.as_bytes() {
231 bytes = v;
232 de::Unexpected::Bytes(&bytes)
233 } else {
234 string = format!("{:?}", self.value);
235 de::Unexpected::Other(&string)
236 };
237
238 de::Error::invalid_type(unexpected, visitor)
239 }
240
241 fn invalid_type<'de, V: de::Visitor<'de>>(&self, visitor: V) -> Result<V::Value> {
242 Err(self.invalid_type_(&visitor))
243 }
244
245 fn as_safe_integer(&self) -> Option<i64> {
246 if Number::is_safe_integer(&self.value) {
247 return Some(self.value.unchecked_into_f64() as i64);
248 }
249 None
250 }
251
252 fn deserialize_from_js_number_signed<'de, V: de::Visitor<'de>>(
253 &self,
254 visitor: V,
255 ) -> Result<V::Value> {
256 match self.as_safe_integer() {
257 Some(v) => visitor.visit_i64(v),
258 _ => self.invalid_type(visitor),
259 }
260 }
261
262 fn deserialize_from_js_number_unsigned<'de, V: de::Visitor<'de>>(
263 &self,
264 visitor: V,
265 ) -> Result<V::Value> {
266 match self.as_safe_integer() {
267 Some(v) if v >= 0 => visitor.visit_u64(v as _),
268 _ => self.invalid_type(visitor),
269 }
270 }
271
272 fn deserialize_from_array<'de, V: de::Visitor<'de>>(
273 &self,
274 visitor: V,
275 array: &Array,
276 ) -> Result<V::Value> {
277 visitor.visit_seq(SeqDeserializer::new(array.iter().map(Deserializer::from)))
278 }
279}
280
281impl<'de> de::Deserializer<'de> for Deserializer {
282 type Error = Error;
283
284 fn deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
285 if self.is_nullish() {
286 visitor.visit_unit()
290 } else if let Some(v) = self.value.as_bool() {
291 visitor.visit_bool(v)
292 } else if self.value.is_bigint() {
293 match i64::try_from(self.value) {
294 Ok(v) => visitor.visit_i64(v),
295 Err(value) => match u64::try_from(value) {
296 Ok(v) => visitor.visit_u64(v),
297 Err(_) => Err(de::Error::custom("Couldn't deserialize i64 or u64 from a BigInt outside i64::MIN..u64::MAX bounds"))
298 }
299 }
300 } else if let Some(v) = self.value.as_f64() {
301 if Number::is_safe_integer(&self.value) {
302 visitor.visit_i64(v as i64)
303 } else {
304 visitor.visit_f64(v)
305 }
306 } else if let Some(v) = self.value.as_string() {
307 visitor.visit_string(v)
308 } else if Array::is_array(&self.value) {
309 self.deserialize_seq(visitor)
310 } else if let Some(bytes) = self.as_bytes() {
311 visitor.visit_byte_buf(bytes)
314 } else if self.value.is_object() &&
315 (!Symbol::iterator().js_in(&self.value) || self.value.has_type::<Map>())
329 {
330 self.deserialize_map(visitor)
331 } else {
332 self.invalid_type(visitor)
333 }
334 }
335
336 fn deserialize_unit<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
337 if self.is_nullish() {
338 visitor.visit_unit()
339 } else {
340 self.invalid_type(visitor)
341 }
342 }
343
344 fn deserialize_unit_struct<V: de::Visitor<'de>>(
345 self,
346 _name: &'static str,
347 visitor: V,
348 ) -> Result<V::Value> {
349 self.deserialize_unit(visitor)
350 }
351
352 fn deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
353 if let Some(v) = self.value.as_bool() {
354 visitor.visit_bool(v)
355 } else {
356 self.invalid_type(visitor)
357 }
358 }
359
360 fn deserialize_f32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
362 self.deserialize_f64(visitor)
363 }
364
365 fn deserialize_f64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
366 if let Some(v) = self.value.as_f64() {
367 visitor.visit_f64(v)
368 } else {
369 self.invalid_type(visitor)
370 }
371 }
372
373 fn deserialize_identifier<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
374 self.deserialize_str(visitor)
375 }
376
377 fn deserialize_str<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
378 self.deserialize_string(visitor)
379 }
380
381 fn deserialize_string<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
382 if let Some(v) = self.value.as_string() {
383 visitor.visit_string(v)
384 } else {
385 self.invalid_type(visitor)
386 }
387 }
388
389 fn deserialize_i8<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
393 self.deserialize_from_js_number_signed(visitor)
394 }
395
396 fn deserialize_i16<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
397 self.deserialize_from_js_number_signed(visitor)
398 }
399
400 fn deserialize_i32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
401 self.deserialize_from_js_number_signed(visitor)
402 }
403
404 fn deserialize_u8<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
405 self.deserialize_from_js_number_unsigned(visitor)
406 }
407
408 fn deserialize_u16<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
409 self.deserialize_from_js_number_unsigned(visitor)
410 }
411
412 fn deserialize_u32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
413 self.deserialize_from_js_number_unsigned(visitor)
414 }
415
416 fn deserialize_i64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
420 if self.value.is_bigint() {
421 match i64::try_from(self.value) {
422 Ok(v) => visitor.visit_i64(v),
423 Err(_) => Err(de::Error::custom(
424 "Couldn't deserialize i64 from a BigInt outside i64::MIN..i64::MAX bounds",
425 )),
426 }
427 } else {
428 self.deserialize_from_js_number_signed(visitor)
429 }
430 }
431
432 fn deserialize_u64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
436 if self.value.is_bigint() {
437 match u64::try_from(self.value) {
438 Ok(v) => visitor.visit_u64(v),
439 Err(_) => Err(de::Error::custom(
440 "Couldn't deserialize u64 from a BigInt outside u64::MIN..u64::MAX bounds",
441 )),
442 }
443 } else {
444 self.deserialize_from_js_number_unsigned(visitor)
445 }
446 }
447
448 fn deserialize_i128<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
451 if self.value.is_bigint() {
452 match i128::try_from(self.value) {
453 Ok(v) => visitor.visit_i128(v),
454 Err(_) => Err(de::Error::custom(
455 "Couldn't deserialize i128 from a BigInt outside i128::MIN..i128::MAX bounds",
456 )),
457 }
458 } else {
459 self.invalid_type(visitor)
460 }
461 }
462
463 fn deserialize_u128<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
466 if self.value.is_bigint() {
467 match u128::try_from(self.value) {
468 Ok(v) => visitor.visit_u128(v),
469 Err(_) => Err(de::Error::custom(
470 "Couldn't deserialize u128 from a BigInt outside u128::MIN..u128::MAX bounds",
471 )),
472 }
473 } else {
474 self.invalid_type(visitor)
475 }
476 }
477
478 fn deserialize_char<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
484 if let Some(s) = self.value.dyn_ref::<JsString>() {
485 if let Some(c) = s.as_char() {
486 return visitor.visit_char(c);
487 }
488 }
489 self.invalid_type(visitor)
490 }
491
492 fn deserialize_option<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
496 if !self.is_nullish() {
497 visitor.visit_some(self)
498 } else {
499 visitor.visit_none()
500 }
501 }
502
503 fn deserialize_newtype_struct<V: de::Visitor<'de>>(
505 self,
506 _name: &'static str,
507 visitor: V,
508 ) -> Result<V::Value> {
509 visitor.visit_newtype_struct(self)
510 }
511
512 fn deserialize_seq<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
518 if let Some(arr) = self.value.dyn_ref::<Array>() {
519 self.deserialize_from_array(visitor, arr)
520 } else if let Some(iter) = js_sys::try_iter(&self.value)? {
521 visitor.visit_seq(SeqAccess { iter })
522 } else {
523 self.invalid_type(visitor)
524 }
525 }
526
527 fn deserialize_tuple<V: de::Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value> {
529 self.deserialize_seq(visitor)
530 }
531
532 fn deserialize_tuple_struct<V: de::Visitor<'de>>(
534 self,
535 name: &'static str,
536 len: usize,
537 visitor: V,
538 ) -> Result<V::Value> {
539 if name == PRESERVED_VALUE_MAGIC {
540 return visitor.visit_seq(PreservedValueAccess::OnMagic(self.value));
541 }
542 self.deserialize_tuple(len, visitor)
543 }
544
545 fn deserialize_map<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
553 match js_sys::try_iter(&self.value)? {
554 Some(iter) => visitor.visit_map(MapAccess::new(iter)),
555 None => match self.as_object_entries() {
556 Some(arr) => visitor.visit_map(MapDeserializer::new(arr.iter().map(convert_pair))),
557 None => self.invalid_type(visitor),
558 },
559 }
560 }
561
562 fn deserialize_struct<V: de::Visitor<'de>>(
568 self,
569 _name: &'static str,
570 fields: &'static [&'static str],
571 visitor: V,
572 ) -> Result<V::Value> {
573 let obj = if self.value.is_object() {
574 self.value.unchecked_into::<ObjectExt>()
575 } else {
576 return self.invalid_type(visitor);
577 };
578 visitor.visit_map(ObjectAccess::new(obj, fields))
579 }
580
581 fn deserialize_enum<V: de::Visitor<'de>>(
585 self,
586 _name: &'static str,
587 _variants: &'static [&'static str],
588 visitor: V,
589 ) -> Result<V::Value> {
590 let access = if self.value.is_string() {
591 EnumAccess {
592 tag: self.value.into(),
593 payload: JsValue::UNDEFINED.into(),
594 }
595 } else if let Some(entries) = self.as_object_entries() {
596 if entries.length() != 1 {
597 return Err(de::Error::invalid_length(entries.length() as _, &"1"));
598 }
599 let entry = entries.get(0);
600 let (tag, payload) = convert_pair(entry);
601 EnumAccess { tag, payload }
602 } else {
603 return self.invalid_type(visitor);
604 };
605 visitor.visit_enum(access)
606 }
607
608 fn deserialize_ignored_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
610 visitor.visit_unit()
611 }
612
613 fn deserialize_bytes<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
615 self.deserialize_byte_buf(visitor)
616 }
617
618 fn deserialize_byte_buf<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
625 if let Some(bytes) = self.as_bytes() {
626 visitor.visit_byte_buf(bytes)
627 } else if let Some(arr) = self.value.dyn_ref::<Array>() {
628 self.deserialize_from_array(visitor, arr)
629 } else {
630 self.invalid_type(visitor)
631 }
632 }
633
634 fn is_human_readable(&self) -> bool {
635 true
636 }
637}
638
639impl<'de> de::VariantAccess<'de> for Deserializer {
640 type Error = Error;
641
642 fn unit_variant(self) -> Result<()> {
643 de::Deserialize::deserialize(self)
644 }
645
646 fn newtype_variant_seed<T: de::DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value> {
647 seed.deserialize(self)
648 }
649
650 fn tuple_variant<V: de::Visitor<'de>>(self, len: usize, visitor: V) -> Result<V::Value> {
651 de::Deserializer::deserialize_tuple(self, len, visitor)
652 }
653
654 fn struct_variant<V: de::Visitor<'de>>(
655 self,
656 fields: &'static [&'static str],
657 visitor: V,
658 ) -> Result<V::Value> {
659 de::Deserializer::deserialize_struct(self, "", fields, visitor)
660 }
661}