serde_wasm_bindgen/
de.rs

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
11/// Provides [`de::SeqAccess`] from any JS iterator.
12struct 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
30/// Provides [`de::MapAccess`] from any JS iterator that returns `[key, value]` pairs.
31struct 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            // If this value is `undefined`, it might be actually a missing field;
96            // double-check with an `in` operator if so.
97            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        // Temporary replacement to avoid borrow checker issues when moving out `JsValue`.
126        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
143/// Provides [`de::EnumAccess`] from given JS values for the `tag` and the `payload`.
144struct 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
161/// A newtype that allows using any [`JsValue`] as a [`de::Deserializer`].
162pub struct Deserializer {
163    value: JsValue,
164}
165
166impl From<JsValue> for Deserializer {
167    fn from(value: JsValue) -> Self {
168        Self { value }
169    }
170}
171
172// Ideally this would be implemented for `JsValue` instead, but we can't because
173// of the orphan rule.
174impl<'de> IntoDeserializer<'de, Error> for Deserializer {
175    type Deserializer = Self;
176
177    fn into_deserializer(self) -> Self::Deserializer {
178        self
179    }
180}
181
182/// Destructures a JS `[key, value]` pair into a tuple of [`Deserializer`]s.
183fn 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            // Ideally we would only treat `undefined` as `()` / `None` which would be semantically closer
287            // to JS definitions, but, unfortunately, WebIDL generates missing values as `null`
288            // and we probably want to support these as well.
289            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            // We need to handle this here because serde uses `deserialize_any`
312            // for internally tagged enums
313            visitor.visit_byte_buf(bytes)
314        } else if self.value.is_object() &&
315            // The only reason we want to support objects here is because serde uses
316            // `deserialize_any` for internally tagged enums
317            // (see https://github.com/RReverser/serde-wasm-bindgen/pull/4#discussion_r352245020).
318            //
319            // We expect such enums to be represented via plain JS objects, so let's explicitly
320            // exclude Sets and other iterables. These should be deserialized via concrete
321            // `deserialize_*` methods instead of us trying to guess the right target type.
322            //
323            // We still do support Map, so that the format described here stays a self-describing
324            // format: we happen to serialize to Map, and it is not ambiguous.
325            //
326            // Hopefully we can rid of these hacks altogether once
327            // https://github.com/serde-rs/serde/issues/1183 is implemented / fixed on serde side.
328            (!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    // Serde happily converts `f64` to `f32` (with checks), so we can forward.
361    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    // Serde happily converts any integer to any integer (with checks), so let's forward all of
390    // these to 64-bit methods to save some space in the generated WASM.
391
392    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    /// Supported inputs:
417    /// - `BigInt` within `i64` boundaries.
418    /// - number within safe integer boundaries.
419    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    /// Supported inputs:
433    /// - `BigInt` within `u64` boundaries.
434    /// - number within safe integer boundaries.
435    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    /// Supported inputs:
449    /// - `BigInt` within `i128` boundaries.
450    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    /// Supported inputs:
464    /// - `BigInt` within `u128` boundaries.
465    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    /// Converts a JavaScript string to a Rust `char`.
479    ///
480    /// By default we don't perform detection of single chars because it's pretty complicated,
481    /// but if we get a hint that they're expected, this methods allows to avoid heap allocations
482    /// of an intermediate `String` by directly converting numeric codepoints instead.
483    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    /// Deserializes `undefined` or `null` into `None` and any other value into `Some(value)`.
493    // Serde can deserialize `visit_unit` into `None`, but can't deserialize arbitrary value
494    // as `Some`, so we need to provide own simple implementation.
495    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    /// Forwards to deserializing newtype contents.
504    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    /// Supported inputs:
513    ///  - JS iterable (an object with [`[Symbol.iterator]`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator)).
514    ///
515    /// Supported outputs:
516    ///  - Any Rust sequence from Serde point of view ([`Vec`], [`HashSet`](std::collections::HashSet), etc.)
517    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    /// Forwards to [`Self::deserialize_seq`](#method.deserialize_seq).
528    fn deserialize_tuple<V: de::Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value> {
529        self.deserialize_seq(visitor)
530    }
531
532    /// Forwards to [`Self::deserialize_tuple`](#method.deserialize_tuple).
533    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    /// Supported inputs:
546    ///  - A JS iterable that is expected to return `[key, value]` pairs.
547    ///  - A JS object, which will be iterated using [`Object.entries`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries).
548    ///
549    /// Supported outputs:
550    ///  - A Rust key-value map ([`HashMap`](std::collections::HashMap), [`BTreeMap`](std::collections::BTreeMap), etc.).
551    ///  - A typed Rust structure with `#[derive(Deserialize)]`.
552    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    /// Supported inputs:
563    ///  - A plain JS object.
564    ///
565    /// Supported outputs:
566    ///  - A typed Rust structure with `#[derive(Deserialize)]`.
567    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    /// Here we try to be compatible with `serde-json`, which means supporting:
582    ///  - `"Variant"` - gets converted to a unit variant `MyEnum::Variant`
583    ///  - `{ Variant: ...payload... }` - gets converted to a `MyEnum::Variant { ...payload... }`.
584    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    /// Ignores any value without calling to the JS side even to check its type.
609    fn deserialize_ignored_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
610        visitor.visit_unit()
611    }
612
613    /// We can't take references to JS memory, so forwards to an owned [`Self::deserialize_byte_buf`](#method.deserialize_byte_buf).
614    fn deserialize_bytes<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
615        self.deserialize_byte_buf(visitor)
616    }
617
618    /// Serde expects `visit_byte_buf` to be called only in response to an explicit `deserialize_bytes`,
619    /// so we provide conversions here.
620    ///
621    /// Supported inputs:
622    ///  - `ArrayBuffer` - converted to an `Uint8Array` view first.
623    ///  - `Uint8Array`, `Array` - copied to a newly created `Vec<u8>` on the Rust side.
624    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}