xmlity/
ser.rs

1//! This module contains the [`Serialize`], [`SerializeAttribute`], [`Serializer`] and [`SerializationGroup`] traits and associated types.
2use std::fmt::Display;
3
4use crate::{ExpandedName, Prefix};
5
6/// A trait for errors that can be returned by serializer after a serialization attempt.
7pub trait Error {
8    /// Creates an error with a custom message.
9    fn custom<T>(msg: T) -> Self
10    where
11        T: Display;
12}
13
14/// A trait for serializing attributes.
15pub trait SerializeAttributes: Sized {
16    /// The type of the value that is returned when serialization is successful.
17    type Ok;
18    /// The type of the error that is returned when serialization fails.
19    type Error: Error;
20
21    /// Serializes an attribute.
22    fn serialize_attribute<A: SerializeAttribute>(
23        &mut self,
24        a: &A,
25    ) -> Result<Self::Ok, Self::Error>;
26}
27
28impl<T: SerializeAttributes> SerializeAttributes for &mut T {
29    type Ok = T::Ok;
30    type Error = T::Error;
31
32    fn serialize_attribute<A: SerializeAttribute>(
33        &mut self,
34        a: &A,
35    ) -> Result<Self::Ok, Self::Error> {
36        SerializeAttributes::serialize_attribute(*self, a)
37    }
38}
39
40/// A trait for serializing elements.
41#[must_use = "Serializers could be lazy and must be consumed to guarantee serialization. Try calling `.serialize_children()` or `.end()` on the serializer."]
42pub trait SerializeElement: SerializeAttributes {
43    /// The type of the value that is returned when serialization is successful.
44    type ChildrenSerializeSeq: SerializeSeq<Ok = Self::Ok, Error = Self::Error>;
45
46    /// Always serialize this element with the given prefix.
47    fn include_prefix(&mut self, should_enforce: IncludePrefix) -> Result<Self::Ok, Self::Error>;
48
49    /// Set the preferred prefix for this element.
50    fn preferred_prefix(
51        &mut self,
52        preferred_prefix: Option<Prefix<'_>>,
53    ) -> Result<Self::Ok, Self::Error>;
54
55    /// Serialize the children of this element.
56    fn serialize_children(self) -> Result<Self::ChildrenSerializeSeq, Self::Error>;
57
58    /// End the serialization of this element with no children.
59    fn end(self) -> Result<Self::Ok, Self::Error>;
60}
61
62/// A trait for serializing a sequence of elements.
63#[must_use = "Serializers could be lazy and must be consumed to guarantee serialization. Try calling `.end()` on the serializer."]
64pub trait SerializeSeq {
65    /// The type of the value that is returned when serialization is successful.
66    type Ok;
67    /// The type of the error that is returned when serialization fails.
68    type Error: Error;
69
70    /// Serialize an element in the sequence.
71    fn serialize_element<V: Serialize>(&mut self, v: &V) -> Result<Self::Ok, Self::Error>;
72
73    /// End the serialization of the sequence.
74    fn end(self) -> Result<Self::Ok, Self::Error>;
75}
76
77/// A serializer receives serialization instructions from a [`Serialize`] implementation and produces serialized output.
78pub trait Serializer: Sized {
79    /// The type of the value that is returned when serialization is successful.
80    type Ok;
81    /// The type of the error that is returned when serialization fails.
82    type Error: Error;
83    /// The type of the serializer that is used to serialize an element with children.
84    type SerializeElement: SerializeElement<Ok = Self::Ok, Error = Self::Error>;
85    /// The type of the serializer that is used to serialize a sequence of elements.
86    type SerializeSeq: SerializeSeq<Ok = Self::Ok, Error = Self::Error>;
87
88    /// Serialize a text node.
89    fn serialize_text<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error>;
90
91    /// Serialize a CDATA section.
92    fn serialize_cdata<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error>;
93
94    /// Serialize an element with children.
95    fn serialize_element(
96        self,
97        name: &'_ ExpandedName<'_>,
98    ) -> Result<Self::SerializeElement, Self::Error>;
99
100    /// Serialize a sequence of elements.
101    fn serialize_seq(self) -> Result<Self::SerializeSeq, Self::Error>;
102
103    /// Serialize an XML declaration.
104    fn serialize_decl<S: AsRef<str>>(
105        self,
106        version: S,
107        encoding: Option<S>,
108        standalone: Option<S>,
109    ) -> Result<Self::Ok, Self::Error>;
110
111    /// Serialize a processing instruction.
112    fn serialize_pi<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error>;
113
114    /// Serialize a comment.
115    fn serialize_comment<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error>;
116
117    /// Serialize a doctype declaration.
118    fn serialize_doctype<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error>;
119
120    /// Serialize nothing.
121    fn serialize_none(self) -> Result<Self::Ok, Self::Error>;
122}
123
124/// A type that can serialize attributes. Works in a similar way to [`Serializer`].
125pub trait AttributeSerializer: Sized {
126    /// The type of the value that is returned when serialization is successful.
127    type Ok;
128    /// The type of the error that is returned when serialization fails.
129    type Error: Error;
130    /// The type returned when serializing an attribute.
131    type SerializeAttribute<'a>: SerializeAttributeAccess<Ok = Self::Ok, Error = Self::Error>
132    where
133        Self: 'a;
134
135    /// Serialize an attribute.
136    fn serialize_attribute(
137        &mut self,
138        name: &'_ ExpandedName<'_>,
139    ) -> Result<Self::SerializeAttribute<'_>, Self::Error>;
140
141    /// Serialize nothing.
142    fn serialize_none(&mut self) -> Result<Self::Ok, Self::Error>;
143}
144
145/// A type that can be serialized. To serialize, you provide it with a [`Serializer`] that then gets instructions from the type on how to serialize itself.
146///
147/// To see the documentation for the derive macro, see [`xmlity_derive::Serialize`].
148pub trait Serialize {
149    /// Serialize the type.
150    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
151}
152
153impl<T: Serialize> Serialize for &T {
154    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
155        T::serialize(*self, serializer)
156    }
157}
158
159impl<T: Serialize> Serialize for &mut T {
160    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
161        T::serialize(*self, serializer)
162    }
163}
164
165/// Setting for whether to enforce a prefix when serializing.
166#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
167pub enum IncludePrefix {
168    /// Always enforce the prefix.
169    Always,
170    /// Only when the preferred prefix is not the used prefix.
171    WhenNecessaryForPreferredPrefix,
172    /// Only use the prefix when it is absolutely necessary.
173    #[default]
174    Never,
175}
176
177/// A type that can be used to serialize an attribute.
178pub trait SerializeAttributeAccess: Sized {
179    /// The type of the value that is returned when serialization is successful.
180    type Ok;
181    /// The type of the error that is returned when serialization fails.
182    type Error: Error;
183
184    /// Set whether to enforce a prefix when serializing.
185    fn include_prefix(&mut self, should_include: IncludePrefix) -> Result<Self::Ok, Self::Error>;
186
187    /// Set the preferred prefix to use when serializing.
188    fn preferred_prefix(
189        &mut self,
190        preferred_prefix: Option<Prefix<'_>>,
191    ) -> Result<Self::Ok, Self::Error>;
192
193    /// Serialize the attribute.
194    fn end<S: AsRef<str>>(self, value: S) -> Result<Self::Ok, Self::Error>;
195}
196
197/// A type that can be serialized as an attribute. Since this is a separate trait from [`Serialize`], it is possible to choose between serializing a type as an attribute or as an element.
198///
199/// To see the documentation for the derive macro, see [`xmlity_derive::SerializeAttribute`].
200pub trait SerializeAttribute: Sized {
201    /// Serialize the attribute.
202    fn serialize_attribute<S: AttributeSerializer>(&self, serializer: S)
203        -> Result<S::Ok, S::Error>;
204}
205
206/// A trait for serializing sub-elements/sub-attributes of a type. This can be used to more easily include common attributes/elements in multiple types, instead of repeating the same code.
207///
208/// To see the documentation for the derive macro, see [`xmlity_derive::SerializationGroup`].
209pub trait SerializationGroup: Sized {
210    /// Serialize the attributes of the type.
211    fn serialize_attributes<S: SerializeAttributes>(
212        &self,
213        serializer: &mut S,
214    ) -> Result<(), S::Error> {
215        let _ = serializer;
216
217        Ok(())
218    }
219
220    /// Serialize the children of the type.
221    fn serialize_children<S: SerializeSeq>(&self, serializer: &mut S) -> Result<(), S::Error> {
222        let _ = serializer;
223
224        Ok(())
225    }
226}