xmlity/
de.rs

1//! This module contains the [`Deserialize`], [`Deserializer`] and [`DeserializationGroup`] traits and associated types.
2
3use std::{
4    borrow::Cow,
5    error::Error as StdError,
6    fmt::{self, Debug, Display},
7};
8
9use crate::{ExpandedName, Prefix, XmlNamespace};
10
11/// A trait for errors that can be returned by a [`Deserializer`].
12pub trait Error: Sized + StdError {
13    /// Error for when a custom error occurs during deserialization.
14    fn custom<T>(msg: T) -> Self
15    where
16        T: Display;
17
18    /// Error for when a name is expected to be a certain value, but it is not.
19    fn wrong_name(name: &ExpandedName<'_>, expected: &ExpandedName<'_>) -> Self;
20
21    /// Error for when a type is expected to be a certain type, but it is not.
22    fn unexpected_visit<T>(unexpected: Unexpected, expected: &T) -> Self;
23
24    /// Error for when a field is missing.
25    fn missing_field(field: &str) -> Self;
26
27    /// Error for when a type has no possible variants to deserialize into.
28    fn no_possible_variant(ident: &str) -> Self;
29
30    /// Error for when a type is missing data that is required to deserialize it.
31    fn missing_data() -> Self;
32
33    /// Error for when a child cannot be identified, and ignoring it is not allowed.
34    fn unknown_child() -> Self;
35
36    /// Error for when a string is invalid for the type.
37    fn invalid_string() -> Self;
38}
39
40/// An enum representing the unexpected type of data that was encountered.
41#[derive(Debug, thiserror::Error)]
42#[non_exhaustive]
43pub enum Unexpected {
44    /// A text node.
45    #[error("text")]
46    Text,
47    /// A CDATA section.
48    #[error("cdata")]
49    CData,
50    /// A sequence of XML values.
51    #[error("sequence")]
52    Seq,
53    /// An element start.
54    #[error("element start")]
55    ElementStart,
56    /// An element end.
57    #[error("element end")]
58    ElementEnd,
59    /// An attribute.
60    #[error("attribute")]
61    Attribute,
62    /// A comment.
63    #[error("comment")]
64    Comment,
65    /// A declaration.
66    #[error("declaration")]
67    Decl,
68    /// A processing instruction.
69    #[error("processing instruction")]
70    PI,
71    /// A doctype.
72    #[error("doctype")]
73    DocType,
74    /// End of file.
75    #[error("eof")]
76    Eof,
77    /// Nothing.
78    #[error("none")]
79    None,
80}
81
82/// Trait that lets you access the namespaces declared on an XML node.
83pub trait NamespaceContext {
84    /// Get the default namespace.
85    fn default_namespace(&self) -> Option<XmlNamespace<'_>>;
86
87    /// Resolve a prefix to a namespace.
88    fn resolve_prefix(&self, prefix: Prefix<'_>) -> Option<XmlNamespace<'_>>;
89}
90
91/// Trait that lets you access the attributes of an XML node.
92pub trait AttributesAccess<'de> {
93    /// The error type for this attributes access.
94    type Error: Error;
95    /// The type of the sub access for this attributes access returned by [`AttributesAccess::sub_access`].
96    type SubAccess<'a>: AttributesAccess<'de, Error = Self::Error> + 'a
97    where
98        Self: 'a;
99
100    /// Get the next attribute.
101    fn next_attribute<T>(&mut self) -> Result<Option<T>, Self::Error>
102    where
103        T: Deserialize<'de>;
104
105    /// Get a sub access to the attributes.
106    fn sub_access(&mut self) -> Result<Self::SubAccess<'_>, Self::Error>;
107}
108
109impl<'de, T: AttributesAccess<'de>> AttributesAccess<'de> for &mut T {
110    type Error = T::Error;
111    type SubAccess<'a>
112        = T::SubAccess<'a>
113    where
114        Self: 'a;
115
116    fn next_attribute<D>(&mut self) -> Result<Option<D>, Self::Error>
117    where
118        D: Deserialize<'de>,
119    {
120        (*self).next_attribute()
121    }
122
123    fn sub_access(&mut self) -> Result<Self::SubAccess<'_>, Self::Error> {
124        (*self).sub_access()
125    }
126}
127
128/// A trait for accessing properties of an element. This is the first stage of element deserialization, where the element's name and attributes are accessed. The second stage is accessing the element's children, which is done by calling [`ElementAccess::children`].
129pub trait ElementAccess<'de>: AttributesAccess<'de> {
130    /// The type of the children accessor returned by [`ElementAccess::children`].
131    type ChildrenAccess: SeqAccess<'de, Error = Self::Error>;
132
133    /// The type of the namespace context returned by [`AttributeAccess::namespace_context`].
134    type NamespaceContext<'a>: NamespaceContext + 'a
135    where
136        Self: 'a;
137
138    /// Returns the name of the element.
139    fn name(&self) -> ExpandedName<'_>;
140
141    /// Returns an accessor for the element's children.
142    fn children(self) -> Result<Self::ChildrenAccess, Self::Error>;
143
144    /// Returns the namespace context for this attribute.
145    fn namespace_context(&self) -> Self::NamespaceContext<'_>;
146}
147
148/// An extension trait for [`ElementAccess`] that provides additional methods.
149pub trait ElementAccessExt<'de>: ElementAccess<'de> {
150    /// Ensures that the element has the given name. If it does not, returns an error.
151    fn ensure_name<E: Error>(&self, name: &ExpandedName) -> Result<(), E>;
152}
153
154impl<'de, T: ElementAccess<'de>> ElementAccessExt<'de> for T {
155    fn ensure_name<E: Error>(&self, name: &ExpandedName) -> Result<(), E> {
156        if self.name() == *name {
157            Ok(())
158        } else {
159            Err(Error::wrong_name(&self.name(), name))
160        }
161    }
162}
163
164/// A trait for accessing properties of an attribute.
165pub trait AttributeAccess<'de> {
166    /// The error type for this attribute access.
167    type Error: Error;
168
169    /// Returns the name of the attribute.
170    fn name(&self) -> ExpandedName<'_>;
171
172    /// Deserializes the value of the attribute.
173    fn value<T>(self) -> Result<T, Self::Error>
174    where
175        T: Deserialize<'de>;
176}
177
178/// An extension trait for [`AttributeAccess`] that provides additional methods.
179pub trait AttributeAccessExt<'de>: AttributeAccess<'de> {
180    /// Ensures that the attribute has the given name.
181    fn ensure_name<E: Error>(&self, name: &ExpandedName) -> Result<(), E>;
182}
183
184impl<'de, T: AttributeAccess<'de>> AttributeAccessExt<'de> for T {
185    fn ensure_name<E: Error>(&self, name: &ExpandedName) -> Result<(), E> {
186        if self.name() == *name {
187            Ok(())
188        } else {
189            Err(Error::wrong_name(&self.name(), name))
190        }
191    }
192}
193
194/// A trait for accessing a sequence of nodes, which could include a mix of elements and text nodes.
195pub trait SeqAccess<'de> {
196    /// The error type for this sequence access.
197    type Error: Error;
198
199    /// The type of the sub-access for this sequence access returned by [`SeqAccess::sub_access`].
200    type SubAccess<'g>: SeqAccess<'de, Error = Self::Error>
201    where
202        Self: 'g;
203
204    /// Gets the next element in the sequence.
205    fn next_element<T>(&mut self) -> Result<Option<T>, Self::Error>
206    where
207        T: Deserialize<'de>;
208
209    /// Gets the next element by trying to deserialize it as a sequence.
210    fn next_element_seq<T>(&mut self) -> Result<Option<T>, Self::Error>
211    where
212        T: Deserialize<'de>;
213
214    /// Gets the sub-access for the current sequence access.
215    fn sub_access(&mut self) -> Result<Self::SubAccess<'_>, Self::Error>;
216}
217
218impl<'de, T: SeqAccess<'de>> SeqAccess<'de> for &mut T {
219    type Error = T::Error;
220    type SubAccess<'g>
221        = T::SubAccess<'g>
222    where
223        Self: 'g;
224
225    fn next_element<U>(&mut self) -> Result<Option<U>, Self::Error>
226    where
227        U: Deserialize<'de>,
228    {
229        (*self).next_element()
230    }
231
232    fn next_element_seq<U>(&mut self) -> Result<Option<U>, Self::Error>
233    where
234        U: Deserialize<'de>,
235    {
236        (*self).next_element_seq()
237    }
238
239    fn sub_access(&mut self) -> Result<Self::SubAccess<'_>, Self::Error> {
240        (*self).sub_access()
241    }
242}
243
244/// Trait for XML text.
245pub trait XmlText<'de> {
246    /// The type of the namespace context returned by [`AttributeAccess::namespace_context`].
247    type NamespaceContext<'a>: NamespaceContext + 'a
248    where
249        Self: 'a;
250
251    /// Returns the owned byte representation of the text.
252    fn into_bytes(self) -> Cow<'de, [u8]>;
253
254    /// Returns the byte representation of the text.
255    fn as_bytes(&self) -> &[u8];
256
257    /// Returns the owned string representation of the text.
258    fn into_string(self) -> Cow<'de, str>;
259
260    /// Returns the string representation of the text.
261    fn as_str(&self) -> &str;
262
263    /// Returns the namespace context of the text.
264    fn namespace_context(&self) -> Self::NamespaceContext<'_>;
265}
266
267/// Trait for XML CDATA.
268pub trait XmlCData<'de> {
269    /// The type of the namespace context returned by [`AttributeAccess::namespace_context`].
270    type NamespaceContext<'a>: NamespaceContext + 'a
271    where
272        Self: 'a;
273
274    /// Returns the owned byte representation of the CDATA.
275    fn into_bytes(self) -> Cow<'de, [u8]>;
276
277    /// Returns the byte representation of the CDATA.
278    fn as_bytes(&self) -> &[u8];
279
280    /// Returns the owned string representation of the CDATA.
281    fn into_string(self) -> Cow<'de, str>;
282
283    /// Returns the string representation of the CDATA.
284    fn as_str(&self) -> &str;
285
286    /// Returns the namespace context of the CDATA.
287    fn namespace_context(&self) -> Self::NamespaceContext<'_>;
288}
289
290/// Trait for XML processing instructions.
291pub trait XmlProcessingInstruction {
292    /// The type of the namespace context returned by [`AttributeAccess::namespace_context`].
293    type NamespaceContext<'a>: NamespaceContext + 'a
294    where
295        Self: 'a;
296
297    /// Returns the target of the PI.
298    fn target(&self) -> &[u8];
299
300    /// Returns the content of the PI.
301    fn content(&self) -> &[u8];
302
303    /// Returns the namespace context of the PI.
304    fn namespace_context(&self) -> Self::NamespaceContext<'_>;
305}
306
307/// Trait for XML declarations.
308pub trait XmlDeclaration {
309    /// The type of the namespace context returned by [`AttributeAccess::namespace_context`].
310    type NamespaceContext<'a>: NamespaceContext + 'a
311    where
312        Self: 'a;
313
314    /// Returns the version value of the declaration.
315    fn version(&self) -> &[u8];
316
317    /// Returns the encoding value of the declaration.
318    fn encoding(&self) -> Option<&[u8]>;
319
320    /// Returns the standalone value of the declaration.
321    fn standalone(&self) -> Option<&[u8]>;
322
323    /// Returns the namespace context of the declaration.
324    fn namespace_context(&self) -> Self::NamespaceContext<'_>;
325}
326
327/// Trait for XML comments.
328pub trait XmlComment<'de> {
329    /// The type of the namespace context returned by [`AttributeAccess::namespace_context`].
330    type NamespaceContext<'a>: NamespaceContext + 'a
331    where
332        Self: 'a;
333
334    /// Returns the owned byte representation of the comment.
335    fn into_bytes(self) -> Cow<'de, [u8]>;
336
337    /// Returns the byte representation of the comment.
338    fn as_bytes(&self) -> &[u8];
339
340    /// Returns the namespace context of the comment.
341    fn namespace_context(&self) -> Self::NamespaceContext<'_>;
342}
343
344/// Trait for XML doctypes.
345pub trait XmlDoctype<'de> {
346    /// The type of the namespace context returned by [`AttributeAccess::namespace_context`].
347    type NamespaceContext<'a>: NamespaceContext + 'a
348    where
349        Self: 'a;
350
351    /// Returns the owned byte representation of the doctype.
352    fn into_bytes(self) -> Cow<'de, [u8]>;
353
354    /// Returns the byte representation of the doctype.
355    fn as_bytes(&self) -> &[u8];
356
357    /// Returns the namespace context of the doctype.
358    fn namespace_context(&self) -> Self::NamespaceContext<'_>;
359}
360
361/// Visitor trait that lets you define how to handle different types of XML nodes.
362pub trait Visitor<'de>: Sized {
363    /// The type of value that this visitor will produce.
364    type Value: Deserialize<'de>;
365
366    /// Returns a description of the type that this visitor expects.
367    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result;
368
369    /// Visits an XML text node.
370    fn visit_text<E, V>(self, value: V) -> Result<Self::Value, E>
371    where
372        E: Error,
373        V: XmlText<'de>,
374    {
375        let _ = value;
376        Err(Error::unexpected_visit(Unexpected::Text, &self))
377    }
378
379    /// Visits an XML CDATA node.
380    fn visit_cdata<E, V>(self, value: V) -> Result<Self::Value, E>
381    where
382        E: Error,
383        V: XmlCData<'de>,
384    {
385        let _ = value;
386        Err(Error::unexpected_visit(Unexpected::CData, &self))
387    }
388
389    /// Visits an XML element.
390    fn visit_element<A>(self, element: A) -> Result<Self::Value, A::Error>
391    where
392        A: ElementAccess<'de>,
393    {
394        let _ = element;
395        Err(Error::unexpected_visit(Unexpected::ElementStart, &self))
396    }
397
398    /// Visits an XML attribute.
399    fn visit_attribute<A>(self, attribute: A) -> Result<Self::Value, A::Error>
400    where
401        A: AttributeAccess<'de>,
402    {
403        let _ = attribute;
404        Err(Error::unexpected_visit(Unexpected::Attribute, &self))
405    }
406
407    /// Visits a sequence of values.
408    fn visit_seq<S>(self, mut sequence: S) -> Result<Self::Value, S::Error>
409    where
410        S: SeqAccess<'de>,
411    {
412        sequence
413            .next_element::<Self::Value>()?
414            .ok_or_else(Error::missing_data)
415    }
416
417    /// Visits an XML PI node.
418    fn visit_pi<E, V>(self, pi: V) -> Result<Self::Value, E>
419    where
420        E: Error,
421        V: XmlProcessingInstruction,
422    {
423        let _ = pi;
424        Err(Error::unexpected_visit(Unexpected::PI, &self))
425    }
426
427    /// Visits a declaration.
428    fn visit_decl<E, V>(self, declaration: V) -> Result<Self::Value, E>
429    where
430        E: Error,
431        V: XmlDeclaration,
432    {
433        let _ = declaration;
434        Err(Error::unexpected_visit(Unexpected::Decl, &self))
435    }
436
437    /// Visits a comment.
438    fn visit_comment<E, V>(self, comment: V) -> Result<Self::Value, E>
439    where
440        E: Error,
441        V: XmlComment<'de>,
442    {
443        let _ = comment;
444        Err(Error::unexpected_visit(Unexpected::Comment, &self))
445    }
446
447    /// Visits a doctype declaration.
448    fn visit_doctype<E, V>(self, doctype: V) -> Result<Self::Value, E>
449    where
450        E: Error,
451        V: XmlDoctype<'de>,
452    {
453        let _ = doctype;
454        Err(Error::unexpected_visit(Unexpected::DocType, &self))
455    }
456
457    /// Visits nothing. This is used when a value is not present.
458    fn visit_none<E>(self) -> Result<Self::Value, E>
459    where
460        E: Error,
461    {
462        Err(Error::unexpected_visit(Unexpected::None, &self))
463    }
464}
465
466/// A type that can be used to deserialize XML documents.
467pub trait Deserializer<'de>: Sized {
468    /// The error type that can be returned from the deserializer.
469    type Error: Error;
470
471    /// Deserializes a value from the deserializer.
472    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
473    where
474        V: Visitor<'de>;
475
476    /// Deserializes a value from the deserializer, but tries to do it from a sequence of values.
477    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
478    where
479        V: Visitor<'de>;
480}
481
482/// A type that can be deserialized from a deserializer. This type has two methods: [`Deserialize::deserialize`] and [`Deserialize::deserialize_seq`]. The latter is used in cases where types can be constructed from multiple nodes, such as constructing a [`std::vec::Vec`] from multiple elements, or a [`std::string::String`] from multiple text nodes that are concatenated together.
483///
484/// To see the documentation for the derive macro, see [`xmlity_derive::Deserialize`].
485pub trait Deserialize<'de>: Sized {
486    /// Deserializes a value from a deserializer.
487    fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error>;
488
489    /// Deserializes a value from a deserializer, but tries to do it from a sequence of values.
490    fn deserialize_seq<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
491        Self::deserialize(reader)
492    }
493}
494
495/// A utility type for easier use of [`Deserialize`] trait without needing to specify the lifetime.
496pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
497impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
498
499/// A group of types that can be deserialized together. While this is being built, the type of a [`DeserializationGroup`] is the [`DeserializationGroup::Builder`] type.
500///
501/// To see the documentation for the derive macro, see [`xmlity_derive::DeserializationGroup`].
502pub trait DeserializationGroup<'de> {
503    /// The type of the builder for this deserialization group returned by [`DeserializationGroup::builder`].
504    type Builder: DeserializationGroupBuilder<'de, Value = Self>;
505
506    /// Initializes the deserialization group builder.
507    fn builder() -> Self::Builder;
508}
509
510/// A builder for a deserialization group. When completed (through [`DeserializationGroupBuilder::finish`]), the builder is converted into the deserialization group type that initated the builder.
511pub trait DeserializationGroupBuilder<'de>: Sized {
512    /// The type of the deserialization group that this builder builds when finished through [`DeserializationGroupBuilder::finish`].
513    type Value;
514
515    /// Returns true if the deserializer made progress
516    fn contribute_attributes<D: AttributesAccess<'de>>(
517        &mut self,
518        access: D,
519    ) -> Result<bool, D::Error> {
520        let _ = access;
521
522        Ok(false)
523    }
524
525    /// This hint function is used to avoid calling [`DeserializationGroupBuilder::contribute_attributes`] unnecessarily.
526    fn attributes_done(&self) -> bool {
527        false
528    }
529
530    /// Returns true if the deserializer made progress
531    fn contribute_elements<D: SeqAccess<'de>>(&mut self, access: D) -> Result<bool, D::Error> {
532        let _ = access;
533
534        Ok(false)
535    }
536
537    /// This hint function is used to avoid calling [`DeserializationGroupBuilder::contribute_elements`] unnecessarily.
538    fn elements_done(&self) -> bool {
539        false
540    }
541
542    /// This function is called after all attributes and elements have been contributed.
543    fn finish<E: Error>(self) -> Result<Self::Value, E>;
544}