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