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 are lazy and must be consumed to perform serialization. Try calling `.end()` on the serializer."]
42pub trait SerializeElement: SerializeAttributes {
43    /// The type of the value that is returned when serialization is successful.
44    type SerializeElementChildren: SerializeElementChildren<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::SerializeElementChildren, 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 children of an element.
63#[must_use = "serializers are lazy and must be consumed to perform serialization. Try calling `.end()` on the serializer."]
64pub trait SerializeChildren: Sized {
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 a child of this element.
71    fn serialize_child<V: Serialize>(&mut self, v: &V) -> Result<Self::Ok, Self::Error>;
72}
73
74impl<S: SerializeChildren> SerializeChildren for &mut S {
75    type Ok = S::Ok;
76    type Error = S::Error;
77    fn serialize_child<V: Serialize>(&mut self, v: &V) -> Result<Self::Ok, Self::Error> {
78        S::serialize_child(self, v)
79    }
80}
81
82/// A trait for ending the serialization of an element with children.
83#[must_use = "serializers are lazy and must be consumed to perform serialization. Try calling `.end()` on the serializer."]
84pub trait SerializeElementChildren: SerializeChildren {
85    /// End the serialization of this element with children.
86    fn end(self) -> Result<Self::Ok, Self::Error>;
87}
88
89/// A trait for serializing a sequence of elements.
90#[must_use = "serializers are lazy and must be consumed to perform serialization. Try calling `.end()` on the serializer."]
91pub trait SerializeSeq {
92    /// The type of the value that is returned when serialization is successful.
93    type Ok;
94    /// The type of the error that is returned when serialization fails.
95    type Error: Error;
96
97    /// Serialize an element in the sequence.
98    fn serialize_element<V: Serialize>(&mut self, v: &V) -> Result<Self::Ok, Self::Error>;
99
100    /// End the serialization of the sequence.
101    fn end(self) -> Result<Self::Ok, Self::Error>;
102}
103
104/// A serializer receives serialization instructions from a [`Serialize`] implementation and produces serialized output.
105pub trait Serializer: Sized {
106    /// The type of the value that is returned when serialization is successful.
107    type Ok;
108    /// The type of the error that is returned when serialization fails.
109    type Error: Error;
110    /// The type of the serializer that is used to serialize an element with children.
111    type SerializeElement: SerializeElement<Ok = Self::Ok, Error = Self::Error>;
112    /// The type of the serializer that is used to serialize a sequence of elements.
113    type SerializeSeq: SerializeSeq<Ok = Self::Ok, Error = Self::Error>;
114
115    /// Serialize a text node.
116    fn serialize_text<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error>;
117
118    /// Serialize a CDATA section.
119    fn serialize_cdata<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error>;
120
121    /// Serialize an element with children.
122    fn serialize_element(
123        self,
124        name: &'_ ExpandedName<'_>,
125    ) -> Result<Self::SerializeElement, Self::Error>;
126
127    /// Serialize a sequence of elements.
128    fn serialize_seq(self) -> Result<Self::SerializeSeq, Self::Error>;
129
130    /// Serialize an XML declaration.
131    fn serialize_decl<S: AsRef<str>>(
132        self,
133        version: S,
134        encoding: Option<S>,
135        standalone: Option<S>,
136    ) -> Result<Self::Ok, Self::Error>;
137
138    /// Serialize a processing instruction.
139    fn serialize_pi<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error>;
140
141    /// Serialize a comment.
142    fn serialize_comment<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error>;
143
144    /// Serialize a doctype declaration.
145    fn serialize_doctype<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error>;
146
147    /// Serialize nothing.
148    fn serialize_none(self) -> Result<Self::Ok, Self::Error>;
149}
150
151/// A type that can serialize attributes. Works in a similar way to [`Serializer`].
152pub trait AttributeSerializer: Sized {
153    /// The type of the value that is returned when serialization is successful.
154    type Ok;
155    /// The type of the error that is returned when serialization fails.
156    type Error: Error;
157    /// The type returned when serializing an attribute.
158    type SerializeAttribute<'a>: SerializeAttributeAccess<Ok = Self::Ok, Error = Self::Error>
159    where
160        Self: 'a;
161
162    /// Serialize an attribute.
163    fn serialize_attribute(
164        &mut self,
165        name: &'_ ExpandedName<'_>,
166    ) -> Result<Self::SerializeAttribute<'_>, Self::Error>;
167
168    /// Serialize nothing.
169    fn serialize_none(&mut self) -> Result<Self::Ok, Self::Error>;
170}
171
172/// 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.
173///
174/// To see the documentation for the derive macro, see [`xmlity_derive::Serialize`].
175pub trait Serialize {
176    /// Serialize the type.
177    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
178}
179
180impl<T: Serialize> Serialize for &T {
181    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
182        T::serialize(*self, serializer)
183    }
184}
185
186impl<T: Serialize> Serialize for &mut T {
187    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
188        T::serialize(*self, serializer)
189    }
190}
191
192/// Setting for whether to enforce a prefix when serializing.
193#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
194pub enum IncludePrefix {
195    /// Always enforce the prefix.
196    Always,
197    /// Only when the preferred prefix is not the used prefix.
198    WhenNecessaryForPreferredPrefix,
199    /// Only use the prefix when it is absolutely necessary.
200    #[default]
201    Never,
202}
203
204/// A type that can be used to serialize an attribute.
205pub trait SerializeAttributeAccess: Sized {
206    /// The type of the value that is returned when serialization is successful.
207    type Ok;
208    /// The type of the error that is returned when serialization fails.
209    type Error: Error;
210
211    /// Set whether to enforce a prefix when serializing.
212    fn include_prefix(&mut self, should_include: IncludePrefix) -> Result<Self::Ok, Self::Error>;
213
214    /// Set the preferred prefix to use when serializing.
215    fn preferred_prefix(
216        &mut self,
217        preferred_prefix: Option<Prefix<'_>>,
218    ) -> Result<Self::Ok, Self::Error>;
219
220    /// Serialize the attribute.
221    fn end<S: AsRef<str>>(self, value: S) -> Result<Self::Ok, Self::Error>;
222}
223
224/// 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.
225///
226/// To see the documentation for the derive macro, see [`xmlity_derive::SerializeAttribute`].
227pub trait SerializeAttribute: Sized {
228    /// Serialize the attribute.
229    fn serialize_attribute<S: AttributeSerializer>(&self, serializer: S)
230        -> Result<S::Ok, S::Error>;
231}
232
233/// 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.
234///
235/// To see the documentation for the derive macro, see [`xmlity_derive::SerializationGroup`].
236pub trait SerializationGroup: Sized {
237    /// Serialize the attributes of the type.
238    fn serialize_attributes<S: SerializeAttributes>(&self, serializer: S) -> Result<(), S::Error> {
239        let _ = serializer;
240
241        Ok(())
242    }
243
244    /// Serialize the children of the type.
245    fn serialize_children<S: SerializeChildren>(&self, serializer: S) -> Result<(), S::Error> {
246        let _ = serializer;
247
248        Ok(())
249    }
250}