xsd_parser/xml/
mixed.rs

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/// Used to represent xml elements with mixed content
14#[derive(Default, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
15pub struct Mixed<T> {
16    /// The actual element
17    pub value: T,
18
19    /// The text after the element
20    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
67/// Implements the [`Serializer`](crate::quick_xml::Serializer) trait for the [`Mixed`] types.
68pub enum MixedSerializer<'ser, T>
69where
70    T: WithSerializer,
71{
72    /// Serialize the inner element.
73    Inner {
74        /// Value that needs to be serialized.
75        value: &'ser Mixed<T>,
76
77        /// Current serializer of the inner value.
78        serializer: T::Serializer<'ser>,
79    },
80
81    /// Serialize the text after the element.
82    TextAfter {
83        /// Current serializer of the text after.
84        serializer: IterSerializer<'ser, Option<&'ser Text>, Text>,
85    },
86
87    /// Serialization is done
88    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
152/// Implements the [`Deserializer`] trait for the [`Mixed`] types.
153pub enum MixedDeserializer<T>
154where
155    T: WithDeserializer,
156{
157    /// Initialize the deserialization.
158    Init,
159
160    /// Deserialize the inner value.
161    Inner {
162        /// Current deserializer of the inner value.
163        deserializer: T::Deserializer,
164    },
165
166    /// Deserialize the text after the inner value.
167    TextAfter {
168        /// Already deserialized inner value.
169        value: T,
170
171        /// Wether any elements are allowed or not.
172        allow_any: bool,
173
174        /// Current deserializer of the text value.
175        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}