1use std::fmt::{Debug, Formatter, Result as FmtResult};
2use std::ops::{Deref, DerefMut};
3
4use quick_xml::events::Event;
5
6use crate::quick_xml::{
7 Deserializer, DeserializerArtifact, DeserializerEvent, DeserializerOutput, DeserializerResult,
8 Error, IterSerializer, WithDeserializer, WithSerializer, XmlReader,
9};
10
11use super::text::{Text, TextDeserializer};
12
13#[derive(Default, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
15pub struct Mixed<T> {
16 pub value: T,
18
19 pub text_after: Option<Text>,
21}
22
23impl<T> Deref for Mixed<T> {
24 type Target = T;
25
26 fn deref(&self) -> &Self::Target {
27 &self.value
28 }
29}
30
31impl<T> DerefMut for Mixed<T> {
32 fn deref_mut(&mut self) -> &mut Self::Target {
33 &mut self.value
34 }
35}
36
37impl<T> WithSerializer for Mixed<T>
38where
39 T: WithSerializer,
40{
41 type Serializer<'x>
42 = MixedSerializer<'x, T>
43 where
44 T: 'x;
45
46 fn serializer<'ser>(
47 &'ser self,
48 name: Option<&'ser str>,
49 is_root: bool,
50 ) -> Result<Self::Serializer<'ser>, Error> {
51 let serializer = self.value.serializer(name, is_root)?;
52
53 Ok(MixedSerializer::Inner {
54 value: self,
55 serializer,
56 })
57 }
58}
59
60impl<T> WithDeserializer for Mixed<T>
61where
62 T: WithDeserializer,
63{
64 type Deserializer = MixedDeserializer<T>;
65}
66
67pub enum MixedSerializer<'ser, T>
69where
70 T: WithSerializer,
71{
72 Inner {
74 value: &'ser Mixed<T>,
76
77 serializer: T::Serializer<'ser>,
79 },
80
81 TextAfter {
83 serializer: IterSerializer<'ser, Option<&'ser Text>, Text>,
85 },
86
87 Done,
89}
90
91impl<T> Debug for MixedSerializer<'_, T>
92where
93 T: WithSerializer,
94{
95 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
96 match self {
97 Self::Inner { serializer, .. } => f
98 .debug_struct("Inner")
99 .field("serializer", serializer)
100 .finish_non_exhaustive(),
101 Self::TextAfter { serializer, .. } => f
102 .debug_struct("TextAfter")
103 .field("serializer", serializer)
104 .finish_non_exhaustive(),
105 Self::Done => write!(f, "Done"),
106 }
107 }
108}
109
110impl<'ser, T> Iterator for MixedSerializer<'ser, T>
111where
112 T: WithSerializer,
113{
114 type Item = Result<Event<'ser>, Error>;
115
116 fn next(&mut self) -> Option<Self::Item> {
117 loop {
118 match self {
119 Self::Inner { value, serializer } => match serializer.next() {
120 Some(Ok(event)) => return Some(Ok(event)),
121 Some(Err(error)) => {
122 *self = Self::Done;
123
124 return Some(Err(error));
125 }
126 None => {
127 let serializer =
128 IterSerializer::new(value.text_after.as_ref(), None, false);
129
130 *self = Self::TextAfter { serializer };
131 }
132 },
133 Self::TextAfter { serializer } => match serializer.next() {
134 Some(Ok(event)) => return Some(Ok(event)),
135 Some(Err(error)) => {
136 *self = Self::Done;
137
138 return Some(Err(error));
139 }
140 None => {
141 *self = Self::Done;
142
143 return None;
144 }
145 },
146 Self::Done => return None,
147 }
148 }
149 }
150}
151
152pub enum MixedDeserializer<T>
154where
155 T: WithDeserializer,
156{
157 Init,
159
160 Inner {
162 deserializer: T::Deserializer,
164 },
165
166 TextAfter {
168 value: T,
170
171 allow_any: bool,
173
174 deserializer: Option<TextDeserializer>,
176 },
177}
178
179impl<T> Debug for MixedDeserializer<T>
180where
181 T: WithDeserializer,
182{
183 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
184 match self {
185 Self::Init => write!(f, "Init"),
186 Self::Inner { deserializer } => f
187 .debug_struct("Inner")
188 .field("deserializer", deserializer)
189 .finish(),
190 Self::TextAfter { deserializer, .. } => f
191 .debug_struct("TextAfter")
192 .field("deserializer", deserializer)
193 .finish_non_exhaustive(),
194 }
195 }
196}
197
198impl<'de, T> Deserializer<'de, Mixed<T>> for MixedDeserializer<T>
199where
200 T: WithDeserializer,
201{
202 fn init<R>(reader: &R, event: Event<'de>) -> DeserializerResult<'de, Mixed<T>>
203 where
204 R: XmlReader,
205 {
206 Self::Init.next(reader, event)
207 }
208
209 #[allow(clippy::too_many_lines)]
210 fn next<R>(mut self, reader: &R, mut event: Event<'de>) -> DeserializerResult<'de, Mixed<T>>
211 where
212 R: XmlReader,
213 {
214 loop {
215 let (next_event, next_state) = match self {
216 x @ (Self::Init | Self::Inner { .. }) => {
217 let output = match x {
218 Self::Init => T::Deserializer::init(reader, event),
219 Self::Inner { deserializer } => deserializer.next(reader, event),
220 Self::TextAfter { .. } => unreachable!(),
221 }?;
222
223 let DeserializerOutput {
224 event,
225 artifact,
226 allow_any,
227 } = output;
228
229 match artifact {
230 DeserializerArtifact::None => {
231 return Ok(DeserializerOutput {
232 event,
233 artifact: DeserializerArtifact::None,
234 allow_any,
235 })
236 }
237 DeserializerArtifact::Deserializer(deserializer) => {
238 return Ok(DeserializerOutput {
239 event,
240 artifact: DeserializerArtifact::Deserializer(Self::Inner {
241 deserializer,
242 }),
243 allow_any,
244 })
245 }
246 DeserializerArtifact::Data(value) => match event {
247 DeserializerEvent::Continue(event) => (
248 event,
249 Self::TextAfter {
250 value,
251 allow_any,
252 deserializer: None,
253 },
254 ),
255 event => {
256 return Ok(DeserializerOutput {
257 event,
258 artifact: DeserializerArtifact::Deserializer(Self::TextAfter {
259 value,
260 allow_any,
261 deserializer: None,
262 }),
263 allow_any,
264 })
265 }
266 },
267 }
268 }
269 Self::TextAfter {
270 value,
271 allow_any,
272 deserializer,
273 } => {
274 let output = if let Some(deserializer) = deserializer {
275 deserializer.next(reader, event)
276 } else {
277 TextDeserializer::init(reader, event)
278 }?;
279
280 let DeserializerOutput {
281 event,
282 artifact,
283 allow_any: _,
284 } = output;
285
286 match artifact {
287 DeserializerArtifact::None => {
288 return Ok(DeserializerOutput {
289 event,
290 artifact: DeserializerArtifact::Deserializer(Self::TextAfter {
291 value,
292 allow_any,
293 deserializer: None,
294 }),
295 allow_any,
296 })
297 }
298 DeserializerArtifact::Data(text_after) => {
299 return Ok(DeserializerOutput {
300 event,
301 artifact: DeserializerArtifact::Data(Mixed {
302 value,
303 text_after: Some(text_after),
304 }),
305 allow_any,
306 })
307 }
308 DeserializerArtifact::Deserializer(deserializer) => {
309 return Ok(DeserializerOutput {
310 artifact: DeserializerArtifact::Deserializer(Self::TextAfter {
311 value,
312 allow_any,
313 deserializer: Some(deserializer),
314 }),
315 event,
316 allow_any,
317 })
318 }
319 }
320 }
321 };
322
323 self = next_state;
324 event = next_event;
325 }
326 }
327
328 fn finish<R>(self, reader: &R) -> Result<Mixed<T>, Error>
329 where
330 R: XmlReader,
331 {
332 match self {
333 Self::Init => unreachable!(),
334 Self::Inner { deserializer } => {
335 let value = deserializer.finish(reader)?;
336
337 Ok(Mixed {
338 value,
339 text_after: None,
340 })
341 }
342 Self::TextAfter {
343 value,
344 allow_any: _,
345 deserializer,
346 } => {
347 let text_after = deserializer.map(|x| x.finish(reader)).transpose()?;
348
349 Ok(Mixed { value, text_after })
350 }
351 }
352 }
353}