Skip to main content

quick_xml/de/
text.rs

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