Coverage Report

Created: 2025-10-31 06:57

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