Skip to main content

quick_xml/de/
simple_type.rs

1//! Contains Serde `Deserializer` for XML [simple types] [as defined] in the XML Schema.
2//!
3//! [simple types]: https://www.w3schools.com/xml/el_simpletype.asp
4//! [as defined]: https://www.w3.org/TR/xmlschema11-1/#Simple_Type_Definition
5
6use crate::XmlVersion;
7use crate::de::Text;
8use crate::errors::serialize::DeError;
9use crate::escape::resolve_predefined_entity;
10use crate::utils::{CowRef, trim_xml_spaces};
11use memchr::memchr;
12use serde::de::value::UnitDeserializer;
13use serde::de::{
14    DeserializeSeed, Deserializer, EnumAccess, IntoDeserializer, SeqAccess, VariantAccess, Visitor,
15};
16use std::borrow::Cow;
17use std::ops::Range;
18
19macro_rules! deserialize_num {
20    ($method:ident => $visit:ident) => {
21        #[inline]
22        fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
23        where
24            V: Visitor<'de>,
25        {
26            let text: &str = self.content.as_ref();
27            match trim_xml_spaces(text).parse() {
28                Ok(number) => visitor.$visit(number),
29                Err(_) => self.deserialize_str(visitor),
30            }
31        }
32    };
33}
34
35macro_rules! deserialize_primitive {
36    ($method:ident) => {
37        fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
38        where
39            V: Visitor<'de>,
40        {
41            let de = AtomicDeserializer {
42                content: self.content()?,
43            };
44            de.$method(visitor)
45        }
46    };
47}
48
49macro_rules! unsupported {
50    (
51        $deserialize:ident
52        $(
53            ($($type:ty),*)
54        )?
55    ) => {
56        #[inline]
57        fn $deserialize<V: Visitor<'de>>(
58            self,
59            $($(_: $type,)*)?
60            visitor: V
61        ) -> Result<V::Value, Self::Error> {
62            // Deserializer methods are only hints, if deserializer could not satisfy
63            // request, it should return the data that it has. It is responsibility
64            // of a Visitor to return an error if it does not understand the data
65            self.deserialize_str(visitor)
66        }
67    };
68}
69
70////////////////////////////////////////////////////////////////////////////////////////////////////
71
72/// A version of [`Cow`] that can borrow from two different buffers, one of them
73/// is a deserializer input, and conceptually contains only part of owned data.
74///
75/// # Lifetimes
76/// - `'de` -- lifetime of the data that deserializer borrow from the parsed input
77/// - `'a` -- lifetime of the data that owned by a deserializer
78enum Content<'de, 'a> {
79    /// An input borrowed from the parsed data
80    Input(&'de str),
81    /// An input borrowed from the buffer owned by another deserializer
82    Slice(&'a str),
83    /// An input taken from an external deserializer, owned by that deserializer.
84    /// Only part of this data, located after offset represented by `usize`, used
85    /// to deserialize data, the other is a garbage that can't be dropped because
86    /// we do not want to make reallocations if they will not required.
87    Owned(String, usize),
88}
89impl<'de, 'a> Content<'de, 'a> {
90    /// Returns string representation of the content
91    fn as_str(&self) -> &str {
92        match self {
93            Content::Input(s) => s,
94            Content::Slice(s) => s,
95            Content::Owned(s, offset) => s.split_at(*offset).1,
96        }
97    }
98}
99
100/// A deserializer that handles ordinary [simple type definition][item] with
101/// `{variety} = atomic`, or an ordinary [simple type] definition with
102/// `{variety} = union` whose basic members are all atomic.
103///
104/// This deserializer can deserialize only primitive types:
105/// - numbers
106/// - booleans
107/// - strings
108/// - units
109/// - options
110/// - unit variants of enums
111///
112/// Identifiers represented as strings and deserialized accordingly.
113///
114/// Deserialization of all other types will provide a string and in most cases
115/// the deserialization will fail because visitor does not expect that.
116///
117/// The `Owned` variant of the content acts as a storage for data, allocated by
118/// an external deserializer that pass it via [`ListIter`].
119///
120/// [item]: https://www.w3.org/TR/xmlschema11-1/#std-item_type_definition
121/// [simple type]: https://www.w3.org/TR/xmlschema11-1/#Simple_Type_Definition
122struct AtomicDeserializer<'de, 'a> {
123    /// Content of the attribute value, text content or CDATA content
124    content: CowRef<'de, 'a, str>,
125}
126
127impl<'de, 'a> Deserializer<'de> for AtomicDeserializer<'de, 'a> {
128    type Error = DeError;
129
130    /// Forwards deserialization to the [`Self::deserialize_str`]
131    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
132    where
133        V: Visitor<'de>,
134    {
135        self.deserialize_str(visitor)
136    }
137
138    /// According to the <https://www.w3.org/TR/xmlschema11-2/#boolean>,
139    /// valid boolean representations are only `"true"`, `"false"`, `"1"`,
140    /// and `"0"`.
141    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
142    where
143        V: Visitor<'de>,
144    {
145        let text: &str = self.content.as_ref();
146        match trim_xml_spaces(text) {
147            "1" | "true" => visitor.visit_bool(true),
148            "0" | "false" => visitor.visit_bool(false),
149            _ => self.content.deserialize_str(visitor),
150        }
151    }
152
153    deserialize_num!(deserialize_i8  => visit_i8);
154    deserialize_num!(deserialize_i16 => visit_i16);
155    deserialize_num!(deserialize_i32 => visit_i32);
156    deserialize_num!(deserialize_i64 => visit_i64);
157
158    deserialize_num!(deserialize_u8  => visit_u8);
159    deserialize_num!(deserialize_u16 => visit_u16);
160    deserialize_num!(deserialize_u32 => visit_u32);
161    deserialize_num!(deserialize_u64 => visit_u64);
162
163    deserialize_num!(deserialize_i128 => visit_i128);
164    deserialize_num!(deserialize_u128 => visit_u128);
165
166    deserialize_num!(deserialize_f32 => visit_f32);
167    deserialize_num!(deserialize_f64 => visit_f64);
168
169    /// Forwards deserialization to the [`Self::deserialize_str`]
170    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
171    where
172        V: Visitor<'de>,
173    {
174        let text: &str = self.content.as_ref();
175        let trimmed = trim_xml_spaces(text);
176        // If string is empty or contains only XML space characters (probably only one),
177        // deserialize as usual string and allow visitor to accept or reject it.
178        // Otherwise trim spaces and allow visitor to accept or reject the rest.
179        if trimmed.is_empty() {
180            self.content.deserialize_str(visitor)
181        } else {
182            visitor.visit_str(trimmed)
183        }
184    }
185
186    /// Supply to the visitor borrowed string, string slice, or owned string
187    /// depending on the kind of input and presence of the escaped data.
188    ///
189    /// If string requires unescaping, then calls [`Visitor::visit_string`] with
190    /// new allocated buffer with unescaped data.
191    ///
192    /// Otherwise calls
193    /// - [`Visitor::visit_borrowed_str`] if data borrowed from the input
194    /// - [`Visitor::visit_str`] if data borrowed from other deserializer
195    /// - [`Visitor::visit_string`] if data owned by this deserializer
196    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
197    where
198        V: Visitor<'de>,
199    {
200        self.content.deserialize_str(visitor)
201    }
202
203    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
204    where
205        V: Visitor<'de>,
206    {
207        self.deserialize_str(visitor)
208    }
209
210    /// If `content` is an empty string then calls [`Visitor::visit_none`],
211    /// otherwise calls [`Visitor::visit_some`] with itself
212    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
213    where
214        V: Visitor<'de>,
215    {
216        let text: &str = self.content.as_ref();
217        if text.is_empty() {
218            visitor.visit_none()
219        } else {
220            visitor.visit_some(self)
221        }
222    }
223
224    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
225    where
226        V: Visitor<'de>,
227    {
228        visitor.visit_unit()
229    }
230
231    /// Forwards deserialization to the [`Self::deserialize_unit`]
232    fn deserialize_unit_struct<V>(
233        self,
234        _name: &'static str,
235        visitor: V,
236    ) -> Result<V::Value, Self::Error>
237    where
238        V: Visitor<'de>,
239    {
240        self.deserialize_unit(visitor)
241    }
242
243    fn deserialize_newtype_struct<V>(
244        self,
245        _name: &'static str,
246        visitor: V,
247    ) -> Result<V::Value, Self::Error>
248    where
249        V: Visitor<'de>,
250    {
251        visitor.visit_newtype_struct(self)
252    }
253
254    fn deserialize_enum<V>(
255        self,
256        _name: &'static str,
257        _variants: &'static [&'static str],
258        visitor: V,
259    ) -> Result<V::Value, Self::Error>
260    where
261        V: Visitor<'de>,
262    {
263        visitor.visit_enum(self)
264    }
265
266    /// Forwards deserialization to the [`Self::deserialize_str`]
267    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
268    where
269        V: Visitor<'de>,
270    {
271        self.deserialize_str(visitor)
272    }
273
274    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
275    where
276        V: Visitor<'de>,
277    {
278        visitor.visit_unit()
279    }
280
281    unsupported!(deserialize_bytes);
282    unsupported!(deserialize_byte_buf);
283    unsupported!(deserialize_seq);
284    unsupported!(deserialize_tuple(usize));
285    unsupported!(deserialize_tuple_struct(&'static str, usize));
286    unsupported!(deserialize_map);
287    unsupported!(deserialize_struct(&'static str, &'static [&'static str]));
288}
289
290impl<'de, 'a> EnumAccess<'de> for AtomicDeserializer<'de, 'a> {
291    type Error = DeError;
292    type Variant = UnitOnly;
293
294    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), DeError>
295    where
296        V: DeserializeSeed<'de>,
297    {
298        let name = seed.deserialize(self)?;
299        Ok((name, UnitOnly))
300    }
301}
302
303////////////////////////////////////////////////////////////////////////////////////////////////////
304
305/// Deserializer of variant data, that supports only unit variants.
306/// Attempt to deserialize newtype will provide [`UnitDeserializer`].
307/// Attempt to deserialize tuple or struct variant will result to call of
308/// [`Visitor::visit_unit`].
309pub struct UnitOnly;
310impl<'de> VariantAccess<'de> for UnitOnly {
311    type Error = DeError;
312
313    #[inline]
314    fn unit_variant(self) -> Result<(), Self::Error> {
315        Ok(())
316    }
317
318    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
319    where
320        T: DeserializeSeed<'de>,
321    {
322        seed.deserialize(UnitDeserializer::<Self::Error>::new())
323    }
324
325    #[inline]
326    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
327    where
328        V: Visitor<'de>,
329    {
330        visitor.visit_unit()
331    }
332
333    #[inline]
334    fn struct_variant<V>(
335        self,
336        _fields: &'static [&'static str],
337        visitor: V,
338    ) -> Result<V::Value, Self::Error>
339    where
340        V: Visitor<'de>,
341    {
342        visitor.visit_unit()
343    }
344}
345
346////////////////////////////////////////////////////////////////////////////////////////////////////
347
348/// Iterator over string sub-slices delimited by one or several spaces.
349/// Contains decoded value of the `simpleType`.
350/// Iteration ends when list contains `None`.
351struct ListIter<'de, 'a> {
352    /// If `Some`, contains unconsumed data of the list
353    content: Option<Content<'de, 'a>>,
354}
355impl<'de, 'a> SeqAccess<'de> for ListIter<'de, 'a> {
356    type Error = DeError;
357
358    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, DeError>
359    where
360        T: DeserializeSeed<'de>,
361    {
362        if let Some(mut content) = self.content.take() {
363            const DELIMITER: u8 = b' ';
364
365            loop {
366                let string = content.as_str();
367                if string.is_empty() {
368                    return Ok(None);
369                }
370                return match memchr(DELIMITER, string.as_bytes()) {
371                    // No delimiters in the `content`, deserialize it as a whole atomic
372                    None => match content {
373                        Content::Input(s) => seed.deserialize(AtomicDeserializer {
374                            content: CowRef::Input(s),
375                        }),
376                        Content::Slice(s) => seed.deserialize(AtomicDeserializer {
377                            content: CowRef::Slice(s),
378                        }),
379                        Content::Owned(s, 0) => seed.deserialize(AtomicDeserializer {
380                            content: CowRef::Owned(s),
381                        }),
382                        Content::Owned(s, offset) => seed.deserialize(AtomicDeserializer {
383                            content: CowRef::Slice(s.split_at(offset).1),
384                        }),
385                    },
386                    // `content` started with a space, skip them all
387                    Some(0) => {
388                        // Skip all spaces
389                        let start = string.as_bytes().iter().position(|ch| *ch != DELIMITER);
390                        content = match (start, content) {
391                            // We cannot find any non-space character, so string contains only spaces
392                            (None, _) => return Ok(None),
393                            // Borrow result from input or deserializer depending on the initial borrowing
394                            (Some(start), Content::Input(s)) => Content::Input(s.split_at(start).1),
395                            (Some(start), Content::Slice(s)) => Content::Slice(s.split_at(start).1),
396                            // Skip additional bytes if we own data
397                            (Some(start), Content::Owned(s, skip)) => {
398                                Content::Owned(s, skip + start)
399                            }
400                        };
401                        continue;
402                    }
403                    // `content` started from an atomic
404                    Some(end) => match content {
405                        // Borrow for the next iteration from input or deserializer depending on
406                        // the initial borrowing
407                        Content::Input(s) => {
408                            let (item, rest) = s.split_at(end);
409                            self.content = Some(Content::Input(rest));
410
411                            seed.deserialize(AtomicDeserializer {
412                                content: CowRef::Input(item),
413                            })
414                        }
415                        Content::Slice(s) => {
416                            let (item, rest) = s.split_at(end);
417                            self.content = Some(Content::Slice(rest));
418
419                            seed.deserialize(AtomicDeserializer {
420                                content: CowRef::Slice(item),
421                            })
422                        }
423                        // Skip additional bytes if we own data for next iteration, but deserialize from
424                        // the borrowed data from our buffer
425                        Content::Owned(s, skip) => {
426                            let rest = s.split_at(skip).1;
427                            let item = rest.split_at(end).0;
428                            let result = seed.deserialize(AtomicDeserializer {
429                                content: CowRef::Slice(item),
430                            });
431
432                            self.content = Some(Content::Owned(s, skip + end));
433
434                            result
435                        }
436                    },
437                }
438                .map(Some);
439            }
440        }
441        Ok(None)
442    }
443}
444
445////////////////////////////////////////////////////////////////////////////////////////////////////
446
447/// A deserializer for an xml probably escaped and encoded value of XSD [simple types].
448/// This deserializer will borrow from the input as much as possible.
449///
450/// `deserialize_any()` returns the whole string that deserializer contains.
451///
452/// Escaping the value is actually not always necessary, for instance when
453/// converting to a float, we don't expect any escapable character anyway.
454/// In that cases deserializer skips unescaping step.
455///
456/// Used for deserialize values from:
457/// - attribute values (`<... ...="value" ...>`)
458/// - mixed text / CDATA content (`<...>text<![CDATA[cdata]]></...>`)
459///
460/// This deserializer processes items as following:
461/// - numbers are parsed from a text content using [`FromStr`]; in case of error
462///   [`Visitor::visit_borrowed_str`], [`Visitor::visit_str`], or [`Visitor::visit_string`]
463///   is called; it is responsibility of the type to return an error if it does
464///   not able to process passed data;
465/// - booleans converted from the text according to the XML [specification]:
466///   - `"true"` and `"1"` converted to `true`;
467///   - `"false"` and `"0"` converted to `false`;
468///   - everything else calls [`Visitor::visit_borrowed_str`], [`Visitor::visit_str`],
469///     or [`Visitor::visit_string`]; it is responsibility of the type to return
470///     an error if it does not able to process passed data;
471/// - strings returned as is;
472/// - characters also returned as strings. If string contain more than one character
473///   or empty, it is responsibility of a type to return an error;
474/// - `Option` always deserialized as `Some` using the same deserializer.
475///   If attribute or text content is missed, then the deserializer even wouldn't
476///   be used, so if it is used, then the value should be;
477/// - units (`()`) and unit structs always deserialized successfully, the content is ignored;
478/// - newtype structs forwards deserialization to the inner type using the same
479///   deserializer;
480/// - sequences, tuples and tuple structs are deserialized as `xs:list`s. Only
481///   sequences of primitive types is possible to deserialize this way and they
482///   should be delimited by a space (` `, `\t`, `\r`, or `\n`);
483/// - structs and maps delegates to [`Self::deserialize_str`] which calls
484///   [`Visitor::visit_borrowed_str`] or [`Visitor::visit_string`]; it is responsibility
485///   of the type to return an error if it does not able to process passed data;
486/// - enums:
487///   - the variant name is deserialized using the same deserializer;
488///   - the content is deserialized using the deserializer that always returns unit (`()`):
489///     - unit variants: just return `()`;
490///     - newtype variants: deserialize from [`UnitDeserializer`];
491///     - tuple and struct variants: call [`Visitor::visit_unit`];
492/// - identifiers are deserialized as strings.
493///
494/// [simple types]: https://www.w3.org/TR/xmlschema11-1/#Simple_Type_Definition
495/// [`FromStr`]: std::str::FromStr
496/// [specification]: https://www.w3.org/TR/xmlschema11-2/#boolean
497pub struct SimpleTypeDeserializer<'de, 'a> {
498    /// - In case of attribute contains escaped attribute value
499    /// - In case of text contains unescaped text value
500    content: CowRef<'de, 'a, str>,
501    /// If `true`, `content` in escaped form and should be unescaped before use
502    is_attr: bool,
503    version: XmlVersion,
504}
505
506impl<'de, 'a> SimpleTypeDeserializer<'de, 'a> {
507    /// Creates a deserializer from a value, that possible borrowed from input.
508    ///
509    /// It is assumed that `text` does not have entities.
510    pub fn from_text(text: Cow<'de, str>) -> Self {
511        let content = match text {
512            Cow::Borrowed(slice) => CowRef::Input(slice),
513            Cow::Owned(content) => CowRef::Owned(content),
514        };
515        Self::new(content, false, XmlVersion::Implicit1_0)
516    }
517    /// Creates a deserializer from an XML text node, that possible borrowed from input.
518    ///
519    /// It is assumed that `text` does not have entities.
520    ///
521    /// This constructor used internally to deserialize from text nodes.
522    pub fn from_text_content(value: Text<'de>) -> Self {
523        Self::from_text(value.text)
524    }
525
526    /// Creates a deserializer from a part of value at specified range.
527    ///
528    /// This constructor used internally to deserialize from attribute values.
529    #[allow(clippy::ptr_arg)]
530    pub(crate) fn from_attr(
531        value: &'a Cow<'de, str>,
532        range: Range<usize>,
533        version: XmlVersion,
534    ) -> Self {
535        let content = match value {
536            Cow::Borrowed(slice) => CowRef::Input(&slice[range]),
537            Cow::Owned(slice) => CowRef::Slice(&slice[range]),
538        };
539        Self::new(content, true, version)
540    }
541
542    /// Constructor for tests
543    #[inline]
544    const fn new(content: CowRef<'de, 'a, str>, is_attr: bool, version: XmlVersion) -> Self {
545        Self {
546            content,
547            is_attr,
548            version,
549        }
550    }
551
552    /// Returns content as a string reference.
553    #[inline]
554    fn content<'b>(&'b self) -> Result<CowRef<'de, 'b, str>, DeError> {
555        let content = match self.content {
556            CowRef::Input(content) => CowRef::Input(content),
557            CowRef::Slice(content) => CowRef::Slice(content),
558            CowRef::Owned(ref content) => CowRef::Slice(content.as_str()),
559        };
560        if self.is_attr {
561            let value =
562                self.version
563                    .normalize_attribute_value(&content, 128, resolve_predefined_entity)?;
564            return Ok(match value {
565                Cow::Borrowed(_) => content,
566                Cow::Owned(value) => CowRef::Owned(value),
567            });
568        }
569        Ok(content)
570    }
571}
572
573impl<'de, 'a> Deserializer<'de> for SimpleTypeDeserializer<'de, 'a> {
574    type Error = DeError;
575
576    /// Forwards deserialization to the [`Self::deserialize_str`]
577    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
578    where
579        V: Visitor<'de>,
580    {
581        self.deserialize_str(visitor)
582    }
583
584    deserialize_primitive!(deserialize_bool);
585
586    deserialize_primitive!(deserialize_i8);
587    deserialize_primitive!(deserialize_i16);
588    deserialize_primitive!(deserialize_i32);
589    deserialize_primitive!(deserialize_i64);
590
591    deserialize_primitive!(deserialize_u8);
592    deserialize_primitive!(deserialize_u16);
593    deserialize_primitive!(deserialize_u32);
594    deserialize_primitive!(deserialize_u64);
595
596    deserialize_primitive!(deserialize_i128);
597    deserialize_primitive!(deserialize_u128);
598
599    deserialize_primitive!(deserialize_f32);
600    deserialize_primitive!(deserialize_f64);
601
602    deserialize_primitive!(deserialize_char);
603    deserialize_primitive!(deserialize_str);
604    deserialize_primitive!(deserialize_string);
605    deserialize_primitive!(deserialize_bytes);
606    deserialize_primitive!(deserialize_byte_buf);
607
608    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
609    where
610        V: Visitor<'de>,
611    {
612        visitor.visit_some(self)
613    }
614
615    #[inline]
616    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
617    where
618        V: Visitor<'de>,
619    {
620        visitor.visit_unit()
621    }
622
623    /// Forwards deserialization to the [`Self::deserialize_unit`]
624    #[inline]
625    fn deserialize_unit_struct<V>(
626        self,
627        _name: &'static str,
628        visitor: V,
629    ) -> Result<V::Value, Self::Error>
630    where
631        V: Visitor<'de>,
632    {
633        self.deserialize_unit(visitor)
634    }
635
636    fn deserialize_newtype_struct<V>(
637        self,
638        _name: &'static str,
639        visitor: V,
640    ) -> Result<V::Value, Self::Error>
641    where
642        V: Visitor<'de>,
643    {
644        visitor.visit_newtype_struct(self)
645    }
646
647    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
648    where
649        V: Visitor<'de>,
650    {
651        let content = match self.content()? {
652            CowRef::Input(s) => Content::Input(s),
653            CowRef::Slice(s) => Content::Slice(s),
654            CowRef::Owned(s) => Content::Owned(s, 0),
655        };
656        visitor.visit_seq(ListIter {
657            content: Some(content),
658        })
659    }
660
661    /// Representation of tuples the same as [sequences][Self::deserialize_seq].
662    #[inline]
663    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
664    where
665        V: Visitor<'de>,
666    {
667        self.deserialize_seq(visitor)
668    }
669
670    /// Representation of named tuples the same as [unnamed tuples][Self::deserialize_tuple].
671    #[inline]
672    fn deserialize_tuple_struct<V>(
673        self,
674        _name: &'static str,
675        len: usize,
676        visitor: V,
677    ) -> Result<V::Value, DeError>
678    where
679        V: Visitor<'de>,
680    {
681        self.deserialize_tuple(len, visitor)
682    }
683
684    unsupported!(deserialize_map);
685    unsupported!(deserialize_struct(&'static str, &'static [&'static str]));
686
687    fn deserialize_enum<V>(
688        self,
689        _name: &'static str,
690        _variants: &'static [&'static str],
691        visitor: V,
692    ) -> Result<V::Value, Self::Error>
693    where
694        V: Visitor<'de>,
695    {
696        visitor.visit_enum(self)
697    }
698
699    /// Forwards deserialization to the [`Self::deserialize_str`]
700    #[inline]
701    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
702    where
703        V: Visitor<'de>,
704    {
705        self.deserialize_str(visitor)
706    }
707
708    #[inline]
709    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
710    where
711        V: Visitor<'de>,
712    {
713        visitor.visit_unit()
714    }
715}
716
717impl<'de, 'a> EnumAccess<'de> for SimpleTypeDeserializer<'de, 'a> {
718    type Error = DeError;
719    type Variant = UnitOnly;
720
721    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), DeError>
722    where
723        V: DeserializeSeed<'de>,
724    {
725        let name = seed.deserialize(self)?;
726        Ok((name, UnitOnly))
727    }
728}
729
730impl<'de, 'a> IntoDeserializer<'de, DeError> for SimpleTypeDeserializer<'de, 'a> {
731    type Deserializer = Self;
732
733    #[inline]
734    fn into_deserializer(self) -> Self {
735        self
736    }
737}
738
739////////////////////////////////////////////////////////////////////////////////////////////////////
740
741#[cfg(test)]
742mod tests {
743    use super::*;
744    use crate::se::QuoteLevel;
745    use crate::se::simple_type::{QuoteTarget, SimpleTypeSerializer};
746    use crate::utils::{ByteBuf, Bytes};
747    use serde::de::IgnoredAny;
748    use serde::{Deserialize, Serialize};
749    use std::collections::HashMap;
750
751    macro_rules! simple_only {
752        ($encoding:ident, $name:ident: $type:ty = $xml:expr => $result:expr) => {
753            #[test]
754            fn $name() {
755                let xml = $xml;
756                let de = SimpleTypeDeserializer::new(
757                    CowRef::Input(xml.as_ref()),
758                    true,
759                    XmlVersion::Implicit1_0,
760                );
761                let data: $type = Deserialize::deserialize(de).unwrap();
762
763                assert_eq!(data, $result);
764            }
765        };
766    }
767
768    macro_rules! simple {
769        ($encoding:ident, $name:ident: $type:ty = $xml:expr => $result:expr) => {
770            #[test]
771            fn $name() {
772                let xml = $xml;
773                let de = SimpleTypeDeserializer::new(
774                    CowRef::Input(xml.as_ref()),
775                    true,
776                    XmlVersion::Implicit1_0,
777                );
778                let data: $type = Deserialize::deserialize(de).unwrap();
779
780                assert_eq!(data, $result);
781
782                // Roundtrip to ensure that serializer corresponds to deserializer
783                assert_eq!(
784                    data.serialize(SimpleTypeSerializer {
785                        writer: String::new(),
786                        target: QuoteTarget::Text,
787                        level: QuoteLevel::Full,
788                    })
789                    .unwrap(),
790                    xml
791                );
792            }
793        };
794    }
795
796    macro_rules! err {
797        ($encoding:ident, $name:ident: $type:ty = $xml:expr => $kind:ident($reason:literal)) => {
798            #[test]
799            fn $name() {
800                let xml = $xml;
801                let de = SimpleTypeDeserializer::new(
802                    CowRef::Input(xml.as_ref()),
803                    true,
804                    XmlVersion::Implicit1_0,
805                );
806                let err = <$type as Deserialize>::deserialize(de).unwrap_err();
807
808                match err {
809                    DeError::$kind(e) => assert_eq!(e, $reason),
810                    _ => panic!(
811                        "Expected `Err({}({}))`, but got `{:?}`",
812                        stringify!($kind),
813                        $reason,
814                        err
815                    ),
816                }
817            }
818        };
819    }
820
821    #[derive(Debug, Deserialize, Serialize, PartialEq)]
822    struct Unit;
823
824    #[derive(Debug, Deserialize, Serialize, PartialEq)]
825    struct Newtype(String);
826
827    #[derive(Debug, Deserialize, Serialize, PartialEq)]
828    struct Tuple((), ());
829
830    #[derive(Debug, Deserialize, Serialize, PartialEq)]
831    struct BorrowedNewtype<'a>(&'a str);
832
833    #[derive(Debug, Deserialize, Serialize, PartialEq)]
834    struct Struct {
835        key: String,
836        val: usize,
837    }
838
839    #[derive(Debug, Deserialize, Serialize, PartialEq)]
840    enum Enum {
841        Unit,
842        Newtype(String),
843        Tuple(String, usize),
844        Struct { key: String, val: usize },
845    }
846
847    #[derive(Debug, Deserialize, PartialEq)]
848    #[serde(field_identifier)]
849    enum Id {
850        Field,
851    }
852
853    #[derive(Debug, Deserialize)]
854    #[serde(transparent)]
855    struct Any(IgnoredAny);
856    impl PartialEq for Any {
857        fn eq(&self, _other: &Any) -> bool {
858            true
859        }
860    }
861
862    /// Tests for deserialize atomic and union values, as defined in XSD specification
863    mod atomic {
864        use super::*;
865        use crate::se::simple_type::AtomicSerializer;
866        use pretty_assertions::assert_eq;
867        use std::ops::Deref;
868
869        /// Checks that given `$input` successfully deserializing into given `$result`
870        macro_rules! deserialized_to_only {
871            ($name:ident: $type:ty = $input:literal => $result:expr) => {
872                #[test]
873                fn $name() {
874                    let de = AtomicDeserializer {
875                        content: CowRef::Input($input),
876                    };
877                    let data: $type = Deserialize::deserialize(de).unwrap();
878
879                    assert_eq!(data, $result);
880                }
881            };
882        }
883
884        /// Checks that given `$input` successfully deserializing into given `$result`
885        /// and the result is serialized back to the `$input`
886        macro_rules! deserialized_to {
887            ($name:ident: $type:ty = $input:literal => $result:expr) => {
888                #[test]
889                fn $name() {
890                    let de = AtomicDeserializer {
891                        content: CowRef::Input($input),
892                    };
893                    let data: $type = Deserialize::deserialize(de).unwrap();
894
895                    assert_eq!(data, $result, "deserialization failed");
896
897                    // Roundtrip to ensure that serializer corresponds to deserializer
898                    let mut buffer = String::new();
899                    let has_written = data
900                        .serialize(AtomicSerializer {
901                            writer: &mut buffer,
902                            target: QuoteTarget::Text,
903                            level: QuoteLevel::Full,
904                            write_delimiter: false,
905                        })
906                        .unwrap();
907                    assert_eq!(buffer, $input, "serialization failed");
908                    assert_eq!(has_written, !buffer.is_empty());
909                }
910            };
911        }
912
913        /// Checks that attempt to deserialize given `$input` as a `$type` results to a
914        /// deserialization error `$kind` with `$reason`
915        macro_rules! err {
916            ($name:ident: $type:ty = $input:literal => $kind:ident($reason:literal)) => {
917                #[test]
918                fn $name() {
919                    let de = AtomicDeserializer {
920                        content: CowRef::Input($input),
921                    };
922                    let err = <$type as Deserialize>::deserialize(de).unwrap_err();
923
924                    match err {
925                        DeError::$kind(e) => assert_eq!(e, $reason),
926                        _ => panic!(
927                            "Expected `Err({}({}))`, but got `{:?}`",
928                            stringify!($kind),
929                            $reason,
930                            err
931                        ),
932                    }
933                }
934            };
935        }
936
937        deserialized_to!(false_: bool = "false" => false);
938        deserialized_to!(true_: bool  = "true" => true);
939
940        deserialized_to!(i8_:  i8  = "-2" => -2);
941        deserialized_to!(i16_: i16 = "-2" => -2);
942        deserialized_to!(i32_: i32 = "-2" => -2);
943        deserialized_to!(i64_: i64 = "-2" => -2);
944
945        deserialized_to!(u8_:  u8  = "3" => 3);
946        deserialized_to!(u16_: u16 = "3" => 3);
947        deserialized_to!(u32_: u32 = "3" => 3);
948        deserialized_to!(u64_: u64 = "3" => 3);
949
950        deserialized_to!(i128_: i128 = "-2" => -2);
951        deserialized_to!(u128_: u128 = "2" => 2);
952
953        deserialized_to!(f32_: f32 = "1.23" => 1.23);
954        deserialized_to!(f64_: f64 = "1.23" => 1.23);
955
956        deserialized_to!(char_unescaped: char = "h" => 'h');
957        err!(char_escaped: char = "&lt;"
958                => Custom("invalid value: string \"&lt;\", expected a character"));
959
960        // AtomicDeserializer and AtomicSerializer are asymmetric:
961        // - AtomicDeserializer operates by already normalized (including unescaped) values
962        // - AtomicSerializer escapes values
963        deserialized_to_only!(string: String = "&lt;escaped&#32;string" => "&lt;escaped&#32;string");
964        // Serializer will escape space. Because borrowing has meaning only for deserializer,
965        // no need to test roundtrip here, it is already tested with non-borrowing version
966        deserialized_to_only!(borrowed_str: &str = "non-escaped string" => "non-escaped string");
967        deserialized_to_only!(escaped_str: &str = "escaped&#32;string" => "escaped&#32;string");
968
969        err!(byte_buf: ByteBuf = "&lt;escaped&#32;string"
970                => Custom("invalid type: string \"&lt;escaped&#32;string\", expected byte data"));
971        err!(borrowed_bytes: Bytes = "non-escaped string"
972                => Custom("invalid type: string \"non-escaped string\", expected borrowed bytes"));
973
974        deserialized_to!(option_none: Option<&str> = "" => None);
975        deserialized_to!(option_some: Option<&str> = "non-escaped-string" => Some("non-escaped-string"));
976
977        deserialized_to_only!(unit: () = "<root>anything</root>" => ());
978        deserialized_to_only!(unit_struct: Unit = "<root>anything</root>" => Unit);
979
980        deserialized_to_only!(newtype_owned: Newtype = "&lt;escaped&#32;string" => Newtype("&lt;escaped&#32;string".into()));
981        // Serializer will escape space. Because borrowing has meaning only for deserializer,
982        // no need to test roundtrip here, it is already tested with non-borrowing version
983        deserialized_to_only!(newtype_borrowed: BorrowedNewtype = "non-escaped string"
984                => BorrowedNewtype("non-escaped string"));
985
986        err!(seq: Vec<()> = "non-escaped string"
987                => Custom("invalid type: string \"non-escaped string\", expected a sequence"));
988        err!(tuple: ((), ()) = "non-escaped string"
989                => Custom("invalid type: string \"non-escaped string\", expected a tuple of size 2"));
990        err!(tuple_struct: Tuple = "non-escaped string"
991                => Custom("invalid type: string \"non-escaped string\", expected tuple struct Tuple"));
992
993        err!(map: HashMap<(), ()> = "non-escaped string"
994                => Custom("invalid type: string \"non-escaped string\", expected a map"));
995        err!(struct_: Struct = "non-escaped string"
996                => Custom("invalid type: string \"non-escaped string\", expected struct Struct"));
997
998        deserialized_to!(enum_unit: Enum = "Unit" => Enum::Unit);
999        err!(enum_newtype: Enum = "Newtype"
1000                => Custom("invalid type: unit value, expected a string"));
1001        err!(enum_tuple: Enum = "Tuple"
1002                => Custom("invalid type: unit value, expected tuple variant Enum::Tuple"));
1003        err!(enum_struct: Enum = "Struct"
1004                => Custom("invalid type: unit value, expected struct variant Enum::Struct"));
1005        err!(enum_other: Enum = "any data"
1006                => Custom("unknown variant `any data`, expected one of `Unit`, `Newtype`, `Tuple`, `Struct`"));
1007
1008        deserialized_to_only!(identifier: Id = "Field" => Id::Field);
1009        deserialized_to_only!(ignored_any: Any = "any data" => Any(IgnoredAny));
1010
1011        /// Checks that deserialization from an owned content is working
1012        #[test]
1013        #[cfg(feature = "encoding")]
1014        fn owned_data() {
1015            let de = AtomicDeserializer {
1016                content: CowRef::Owned("string slice".into()),
1017            };
1018            assert_eq!(de.content.deref(), "string slice");
1019
1020            let data: String = Deserialize::deserialize(de).unwrap();
1021            assert_eq!(data, "string slice");
1022        }
1023
1024        /// Checks that deserialization from a content borrowed from some
1025        /// buffer other that input is working
1026        #[test]
1027        fn borrowed_from_deserializer() {
1028            let de = AtomicDeserializer {
1029                content: CowRef::Slice("string slice"),
1030            };
1031            assert_eq!(de.content.deref(), "string slice");
1032
1033            let data: String = Deserialize::deserialize(de).unwrap();
1034            assert_eq!(data, "string slice");
1035        }
1036    }
1037
1038    /// Module for testing list accessor
1039    mod list {
1040        use super::*;
1041        use pretty_assertions::assert_eq;
1042
1043        #[test]
1044        fn empty() {
1045            let mut seq = ListIter {
1046                content: Some(Content::Input("")),
1047            };
1048
1049            assert_eq!(seq.next_element::<&str>().unwrap(), None);
1050            assert_eq!(seq.next_element::<&str>().unwrap(), None);
1051        }
1052
1053        #[test]
1054        fn only_spaces() {
1055            let mut seq = ListIter {
1056                content: Some(Content::Input("  ")),
1057            };
1058
1059            assert_eq!(seq.next_element::<&str>().unwrap(), None);
1060            assert_eq!(seq.next_element::<&str>().unwrap(), None);
1061        }
1062
1063        #[test]
1064        fn one_item() {
1065            let mut seq = ListIter {
1066                content: Some(Content::Input("abc")),
1067            };
1068
1069            assert_eq!(seq.next_element::<&str>().unwrap(), Some("abc"));
1070            assert_eq!(seq.next_element::<&str>().unwrap(), None);
1071            assert_eq!(seq.next_element::<&str>().unwrap(), None);
1072        }
1073
1074        #[test]
1075        fn two_items() {
1076            let mut seq = ListIter {
1077                content: Some(Content::Input("abc def")),
1078            };
1079
1080            assert_eq!(seq.next_element::<&str>().unwrap(), Some("abc"));
1081            assert_eq!(seq.next_element::<&str>().unwrap(), Some("def"));
1082            assert_eq!(seq.next_element::<&str>().unwrap(), None);
1083            assert_eq!(seq.next_element::<&str>().unwrap(), None);
1084        }
1085
1086        #[test]
1087        fn leading_spaces() {
1088            let mut seq = ListIter {
1089                content: Some(Content::Input("  def")),
1090            };
1091
1092            assert_eq!(seq.next_element::<&str>().unwrap(), Some("def"));
1093            assert_eq!(seq.next_element::<&str>().unwrap(), None);
1094            assert_eq!(seq.next_element::<&str>().unwrap(), None);
1095        }
1096
1097        #[test]
1098        fn trailing_spaces() {
1099            let mut seq = ListIter {
1100                content: Some(Content::Input("abc  ")),
1101            };
1102
1103            assert_eq!(seq.next_element::<&str>().unwrap(), Some("abc"));
1104            assert_eq!(seq.next_element::<&str>().unwrap(), None);
1105            assert_eq!(seq.next_element::<&str>().unwrap(), None);
1106        }
1107
1108        #[test]
1109        fn mixed_types() {
1110            let mut seq = ListIter {
1111                content: Some(Content::Input("string 1.23 42 true false h Unit")),
1112            };
1113
1114            assert_eq!(seq.next_element::<&str>().unwrap(), Some("string"));
1115            assert_eq!(seq.next_element::<f32>().unwrap(), Some(1.23));
1116            assert_eq!(seq.next_element::<u32>().unwrap(), Some(42));
1117            assert_eq!(seq.next_element::<bool>().unwrap(), Some(true));
1118            assert_eq!(seq.next_element::<bool>().unwrap(), Some(false));
1119            assert_eq!(seq.next_element::<char>().unwrap(), Some('h'));
1120            assert_eq!(seq.next_element::<Enum>().unwrap(), Some(Enum::Unit));
1121            assert_eq!(seq.next_element::<()>().unwrap(), None);
1122            assert_eq!(seq.next_element::<()>().unwrap(), None);
1123        }
1124    }
1125    // SimpleTypeDeserializer will only ever receive UTF-8 data. DecodingReader
1126    // transcodes non-UTF-8 sources before the parser sees them.
1127    mod utf8 {
1128        use super::*;
1129        use pretty_assertions::assert_eq;
1130
1131        simple!(utf8, i8_:  i8  = "-2" => -2);
1132        simple!(utf8, i16_: i16 = "-2" => -2);
1133        simple!(utf8, i32_: i32 = "-2" => -2);
1134        simple!(utf8, i64_: i64 = "-2" => -2);
1135
1136        simple!(utf8, u8_:  u8  = "3" => 3);
1137        simple!(utf8, u16_: u16 = "3" => 3);
1138        simple!(utf8, u32_: u32 = "3" => 3);
1139        simple!(utf8, u64_: u64 = "3" => 3);
1140
1141        simple!(utf8, i128_: i128 = "-2" => -2);
1142        simple!(utf8, u128_: u128 = "2" => 2);
1143
1144        simple!(utf8, f32_: f32 = "1.23" => 1.23);
1145        simple!(utf8, f64_: f64 = "1.23" => 1.23);
1146
1147        simple!(utf8, false_: bool = "false" => false);
1148        simple!(utf8, true_: bool  = "true" => true);
1149        simple!(utf8, char_unescaped: char = "h" => 'h');
1150        simple!(utf8, char_escaped: char = "&lt;" => '<');
1151
1152        simple!(utf8, string: String = "&lt;escaped string" => "<escaped string");
1153        err!(utf8, byte_buf: ByteBuf = "&lt;escaped&#32;string"
1154             => Custom("invalid type: string \"<escaped string\", expected byte data"));
1155
1156        simple!(utf8, borrowed_str: &str = "non-escaped string" => "non-escaped string");
1157        err!(utf8, borrowed_bytes: Bytes = "&lt;escaped&#32;string"
1158             => Custom("invalid type: string \"<escaped string\", expected borrowed bytes"));
1159
1160        simple!(utf8, option_none: Option<&str> = "" => Some(""));
1161        simple!(utf8, option_some: Option<&str> = "non-escaped string" => Some("non-escaped string"));
1162
1163        simple_only!(utf8, unit: () = "any data" => ());
1164        simple_only!(utf8, unit_struct: Unit = "any data" => Unit);
1165
1166        // Serializer will not escape space because this is unnecessary.
1167        // Because borrowing has meaning only for deserializer, no need to test
1168        // roundtrip here, it is already tested for strings where compatible list
1169        // of escaped characters is used
1170        simple_only!(utf8, newtype_owned: Newtype = "&lt;escaped&#32;string"
1171            => Newtype("<escaped string".into()));
1172        simple_only!(utf8, newtype_borrowed: BorrowedNewtype = "non-escaped string"
1173            => BorrowedNewtype("non-escaped string"));
1174
1175        err!(utf8, map: HashMap<(), ()> = "any data"
1176             => Custom("invalid type: string \"any data\", expected a map"));
1177        err!(utf8, struct_: Struct = "any data"
1178             => Custom("invalid type: string \"any data\", expected struct Struct"));
1179
1180        simple!(utf8, enum_unit: Enum = "Unit" => Enum::Unit);
1181        err!(utf8, enum_newtype: Enum = "Newtype"
1182             => Custom("invalid type: unit value, expected a string"));
1183        err!(utf8, enum_tuple: Enum = "Tuple"
1184             => Custom("invalid type: unit value, expected tuple variant Enum::Tuple"));
1185        err!(utf8, enum_struct: Enum = "Struct"
1186             => Custom("invalid type: unit value, expected struct variant Enum::Struct"));
1187        err!(utf8, enum_other: Enum = "any data"
1188             => Custom("unknown variant `any data`, expected one of `Unit`, `Newtype`, `Tuple`, `Struct`"));
1189
1190        simple_only!(utf8, identifier: Id = "Field" => Id::Field);
1191        simple_only!(utf8, ignored_any: Any = "any data" => Any(IgnoredAny));
1192    }
1193}