quick_xml/de/
text.rs

1use crate::{
2    de::simple_type::SimpleTypeDeserializer,
3    de::{str2bool, Text, TEXT_KEY},
4    errors::serialize::DeError,
5};
6use serde::de::value::BorrowedStrDeserializer;
7use serde::de::{DeserializeSeed, Deserializer, EnumAccess, VariantAccess, Visitor};
8use serde::serde_if_integer128;
9use std::borrow::Cow;
10
11/// A deserializer for a single text node of a mixed sequence of tags and text.
12///
13/// This deserializer are very similar to a [`MapValueDeserializer`] (when it
14/// processes the [`DeEvent::Text`] event). The only difference in the
15/// `deserialize_seq` method. This deserializer will perform deserialization
16/// from a textual content, whereas the [`MapValueDeserializer`] will iterate
17/// over tags / text within it's parent tag.
18///
19/// This deserializer processes items as following:
20/// - numbers are parsed from a text content using [`FromStr`];
21/// - booleans converted from the text according to the XML [specification]:
22///   - `"true"` and `"1"` converted to `true`;
23///   - `"false"` and `"0"` converted to `false`;
24/// - strings returned as is;
25/// - characters also returned as strings. If string contain more than one character
26///   or empty, it is responsibility of a type to return an error;
27/// - `Option`:
28///   - empty text is deserialized as `None`;
29///   - everything else is deserialized as `Some` using the same deserializer;
30/// - units (`()`) and unit structs always deserialized successfully;
31/// - newtype structs forwards deserialization to the inner type using the same
32///   deserializer;
33/// - sequences, tuples and tuple structs are deserialized using [`SimpleTypeDeserializer`]
34///   (this is the difference): text content passed to the deserializer directly;
35/// - structs and maps returns [`DeError::ExpectedStart`];
36/// - enums:
37///   - the variant name is deserialized as `$text`;
38///   - the content is deserialized using the same deserializer:
39///     - unit variants: just return `()`;
40///     - newtype variants forwards deserialization to the inner type using the
41///       same deserializer;
42///     - tuple and struct variants are deserialized using [`SimpleTypeDeserializer`].
43///
44/// [`MapValueDeserializer`]: ../map/struct.MapValueDeserializer.html
45/// [`DeEvent::Text`]: crate::de::DeEvent::Text
46/// [`FromStr`]: std::str::FromStr
47/// [specification]: https://www.w3.org/TR/xmlschema11-2/#boolean
48pub struct TextDeserializer<'de>(pub Text<'de>);
49
50impl<'de> TextDeserializer<'de> {
51    /// Returns a next string as concatenated content of consequent [`Text`] and
52    /// [`CData`] events, used inside [`deserialize_primitives!()`].
53    ///
54    /// [`Text`]: crate::events::Event::Text
55    /// [`CData`]: crate::events::Event::CData
56    #[inline]
57    fn read_string(self) -> Result<Cow<'de, str>, DeError> {
58        Ok(self.0.text)
59    }
60}
61
62impl<'de> Deserializer<'de> for TextDeserializer<'de> {
63    type Error = DeError;
64
65    deserialize_primitives!();
66
67    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
68    where
69        V: Visitor<'de>,
70    {
71        visitor.visit_unit()
72    }
73
74    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
75    where
76        V: Visitor<'de>,
77    {
78        if self.0.is_empty() {
79            visitor.visit_none()
80        } else {
81            visitor.visit_some(self)
82        }
83    }
84
85    /// Forwards deserialization of the inner type. Always calls [`Visitor::visit_newtype_struct`]
86    /// with this deserializer.
87    fn deserialize_newtype_struct<V>(
88        self,
89        _name: &'static str,
90        visitor: V,
91    ) -> Result<V::Value, Self::Error>
92    where
93        V: Visitor<'de>,
94    {
95        visitor.visit_newtype_struct(self)
96    }
97
98    /// This method deserializes a sequence inside of element that itself is a
99    /// sequence element:
100    ///
101    /// ```xml
102    /// <>
103    ///   ...
104    ///   inner sequence as xs:list
105    ///   ...
106    /// </>
107    /// ```
108    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
109    where
110        V: Visitor<'de>,
111    {
112        SimpleTypeDeserializer::from_text_content(self.0).deserialize_seq(visitor)
113    }
114
115    #[inline]
116    fn deserialize_struct<V>(
117        self,
118        _name: &'static str,
119        _fields: &'static [&'static str],
120        _visitor: V,
121    ) -> Result<V::Value, Self::Error>
122    where
123        V: Visitor<'de>,
124    {
125        Err(DeError::ExpectedStart)
126    }
127
128    fn deserialize_enum<V>(
129        self,
130        _name: &'static str,
131        _variants: &'static [&'static str],
132        visitor: V,
133    ) -> Result<V::Value, Self::Error>
134    where
135        V: Visitor<'de>,
136    {
137        visitor.visit_enum(self)
138    }
139
140    #[inline]
141    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
142    where
143        V: Visitor<'de>,
144    {
145        self.deserialize_str(visitor)
146    }
147}
148
149impl<'de> EnumAccess<'de> for TextDeserializer<'de> {
150    type Error = DeError;
151    type Variant = Self;
152
153    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
154    where
155        V: DeserializeSeed<'de>,
156    {
157        let name = seed.deserialize(BorrowedStrDeserializer::<DeError>::new(TEXT_KEY))?;
158        Ok((name, self))
159    }
160}
161
162impl<'de> VariantAccess<'de> for TextDeserializer<'de> {
163    type Error = DeError;
164
165    #[inline]
166    fn unit_variant(self) -> Result<(), Self::Error> {
167        Ok(())
168    }
169
170    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
171    where
172        T: DeserializeSeed<'de>,
173    {
174        seed.deserialize(self)
175    }
176
177    #[inline]
178    fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
179    where
180        V: Visitor<'de>,
181    {
182        self.deserialize_tuple(len, visitor)
183    }
184
185    #[inline]
186    fn struct_variant<V>(
187        self,
188        fields: &'static [&'static str],
189        visitor: V,
190    ) -> Result<V::Value, Self::Error>
191    where
192        V: Visitor<'de>,
193    {
194        self.deserialize_struct("", fields, visitor)
195    }
196}