xsd_parser/xml/
text.rs

1use std::borrow::Cow;
2use std::fmt::{Display, Formatter, Result as FmtResult};
3use std::mem::replace;
4use std::ops::{Deref, DerefMut};
5use std::str::from_utf8;
6
7use quick_xml::escape::{escape, unescape};
8use quick_xml::events::{BytesText, Event};
9
10use crate::quick_xml::{
11    Deserializer, DeserializerArtifact, DeserializerEvent, DeserializerOutput, DeserializerResult,
12    Error, ErrorKind, WithDeserializer, WithSerializer, XmlReader,
13};
14
15/// Type to represent text values inside a XML.
16#[derive(
17    Default,
18    Debug,
19    Clone,
20    Hash,
21    Eq,
22    PartialEq,
23    Ord,
24    PartialOrd,
25    serde::Serialize,
26    serde::Deserialize,
27)]
28pub struct Text(pub String);
29
30impl Text {
31    /// Create a new [`Text`] instance from the passed `value`.
32    #[must_use]
33    pub fn new<S: Into<String>>(value: S) -> Self {
34        Self(value.into())
35    }
36
37    /// Return the content of this text object as string slice.
38    #[must_use]
39    pub fn as_str(&self) -> &str {
40        &self.0
41    }
42}
43
44impl Display for Text {
45    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
46        self.0.fmt(f)
47    }
48}
49
50impl<X> From<X> for Text
51where
52    X: Into<String>,
53{
54    fn from(value: X) -> Self {
55        Self::new(value)
56    }
57}
58
59impl Deref for Text {
60    type Target = String;
61
62    fn deref(&self) -> &Self::Target {
63        &self.0
64    }
65}
66
67impl DerefMut for Text {
68    fn deref_mut(&mut self) -> &mut Self::Target {
69        &mut self.0
70    }
71}
72
73impl WithSerializer for Text {
74    type Serializer<'x> = TextSerializer<'x>;
75
76    fn serializer<'ser>(
77        &'ser self,
78        name: Option<&'ser str>,
79        is_root: bool,
80    ) -> Result<Self::Serializer<'ser>, crate::quick_xml::Error> {
81        let _name = name;
82        let _is_root = is_root;
83
84        Ok(TextSerializer::Emit { value: self })
85    }
86}
87
88impl WithDeserializer for Text {
89    type Deserializer = TextDeserializer;
90}
91
92/// Implemented the [`Serializer`](crate::quick_xml::Serializer) trait for [`Text`].
93#[derive(Debug)]
94pub enum TextSerializer<'ser> {
95    /// Emit events for the contained text value.
96    Emit {
97        /// Value to emit events for.
98        value: &'ser Text,
99    },
100
101    /// Serialization is done.
102    Done,
103}
104
105impl<'ser> Iterator for TextSerializer<'ser> {
106    type Item = Result<Event<'ser>, Error>;
107
108    fn next(&mut self) -> Option<Self::Item> {
109        match replace(self, Self::Done) {
110            Self::Emit { value } => {
111                Some(Ok(Event::Text(BytesText::from_escaped(escape(&value.0)))))
112            }
113            Self::Done => None,
114        }
115    }
116}
117
118/// Implemented the [`Deserializer`] trait for [`Text`].
119#[derive(Debug)]
120pub enum TextDeserializer {
121    /// Init the deserializer
122    Init,
123
124    /// Deserialize text elements.
125    Text {
126        /// Already deserialized text elements.
127        value: Text,
128    },
129}
130
131impl<'de> Deserializer<'de, Text> for TextDeserializer {
132    fn init<R>(reader: &R, event: Event<'de>) -> DeserializerResult<'de, Text>
133    where
134        R: XmlReader,
135    {
136        Self::Init.next(reader, event)
137    }
138
139    fn next<R>(self, reader: &R, event: Event<'de>) -> DeserializerResult<'de, Text>
140    where
141        R: XmlReader,
142    {
143        let _reader = reader;
144
145        let text = match event {
146            Event::Text(x) => x.decode()?,
147            Event::CData(x) => x.decode()?,
148            Event::GeneralRef(x) => {
149                let x = from_utf8(x.as_ref())?;
150
151                Cow::Owned(format!("&{x};"))
152            }
153            event @ (Event::Start(_) | Event::Empty(_) | Event::End(_)) => {
154                let artifact = match self {
155                    Self::Init => DeserializerArtifact::None,
156                    Self::Text { value } => DeserializerArtifact::Data(value),
157                };
158
159                return Ok(DeserializerOutput {
160                    event: DeserializerEvent::Continue(event),
161                    artifact,
162                    allow_any: false,
163                });
164            }
165            event => {
166                let artifact = match self {
167                    Self::Init => DeserializerArtifact::None,
168                    Self::Text { value } => {
169                        DeserializerArtifact::Deserializer(Self::Text { value })
170                    }
171                };
172
173                return Ok(DeserializerOutput {
174                    event: DeserializerEvent::Break(event),
175                    artifact,
176                    allow_any: false,
177                });
178            }
179        };
180
181        let mut value = match self {
182            Self::Init => Text::default(),
183            Self::Text { value } => value,
184        };
185
186        let text = unescape(&text)?;
187        value.0.push_str(&text);
188
189        Ok(DeserializerOutput {
190            event: DeserializerEvent::None,
191            artifact: DeserializerArtifact::Deserializer(Self::Text { value }),
192            allow_any: false,
193        })
194    }
195
196    fn finish<R>(self, reader: &R) -> Result<Text, Error>
197    where
198        R: XmlReader,
199    {
200        let _reader = reader;
201
202        match self {
203            Self::Init => Err(ErrorKind::MissingContent.into()),
204            Self::Text { value } => Ok(value),
205        }
206    }
207}