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#[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 #[must_use]
33 pub fn new<S: Into<String>>(value: S) -> Self {
34 Self(value.into())
35 }
36
37 #[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#[derive(Debug)]
94pub enum TextSerializer<'ser> {
95 Emit {
97 value: &'ser Text,
99 },
100
101 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#[derive(Debug)]
120pub enum TextDeserializer {
121 Init,
123
124 Text {
126 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}