xmlity/
ser.rs

1//! This module contains the [`Serialize`], [`SerializeAttribute`], [`Serializer`] and [`SerializationGroup`] traits and associated types.
2use std::fmt::{Debug, Display};
3
4use crate::{ExpandedName, Prefix};
5
6/// An enum representing the unexpected type of data that was expected.
7#[derive(Debug, thiserror::Error)]
8#[non_exhaustive]
9pub enum Unexpected {
10    /// A text node.
11    #[error("text")]
12    Text,
13    /// A CDATA section.
14    #[error("cdata")]
15    CData,
16    /// A sequence of XML values.
17    #[error("sequence")]
18    Seq,
19    /// An element.
20    #[error("element")]
21    Element,
22    /// An attribute.
23    #[error("attribute")]
24    Attribute,
25    /// A comment.
26    #[error("comment")]
27    Comment,
28    /// A declaration.
29    #[error("declaration")]
30    Decl,
31    /// A processing instruction.
32    #[error("processing instruction")]
33    PI,
34    /// A doctype.
35    #[error("doctype")]
36    DocType,
37    /// End of file.
38    #[error("eof")]
39    Eof,
40    /// Nothing.
41    #[error("none")]
42    None,
43}
44
45/// A trait for errors that can be returned by serializer after a serialization attempt.
46pub trait Error {
47    /// Error for when a serializer expects a certain type, but it is not.
48    fn unexpected_serialize(unexpected: Unexpected) -> Self;
49
50    /// Creates an error with a custom message.
51    fn custom<T>(msg: T) -> Self
52    where
53        T: Display;
54}
55
56/// A trait for serializing attributes.
57pub trait SerializeAttributes: Sized {
58    /// The type of the value that is returned when serialization is successful.
59    type Ok;
60    /// The type of the error that is returned when serialization fails.
61    type Error: Error;
62
63    /// Serializes an attribute.
64    fn serialize_attribute<A: SerializeAttribute>(
65        &mut self,
66        a: &A,
67    ) -> Result<Self::Ok, Self::Error>;
68}
69
70impl<T: SerializeAttributes> SerializeAttributes for &mut T {
71    type Ok = T::Ok;
72    type Error = T::Error;
73
74    fn serialize_attribute<A: SerializeAttribute>(
75        &mut self,
76        a: &A,
77    ) -> Result<Self::Ok, Self::Error> {
78        SerializeAttributes::serialize_attribute(*self, a)
79    }
80}
81
82/// A trait for serializing attributes of an element.
83pub trait SerializeElementAttributes: SerializeAttributes {
84    /// The type of the value that is returned when serialization is successful.
85    type ChildrenSerializeSeq: SerializeSeq<Ok = Self::Ok, Error = Self::Error>;
86
87    /// Serialize the children of this element.
88    fn serialize_children(self) -> Result<Self::ChildrenSerializeSeq, Self::Error>;
89
90    /// End the serialization of this element with no children.
91    fn end(self) -> Result<Self::Ok, Self::Error>;
92}
93
94/// A trait for serializing elements.
95#[must_use = "Serializers could be lazy and must be consumed to guarantee serialization. Try calling `.serialize_children()` or `.end()` on the serializer."]
96pub trait SerializeElement {
97    /// The type of the value that is returned when serialization is successful.
98    type Ok;
99    /// The type of the error that is returned when serialization fails.
100    type Error: Error;
101
102    /// The type of the serializer that is returned when serializing the children of this element.
103    type ChildrenSerializeSeq: SerializeSeq<Ok = Self::Ok, Error = Self::Error>;
104
105    /// The type of the serializer that is returned when serializing the attributes of this element.
106    type SerializeElementAttributes: SerializeElementAttributes<Ok = Self::Ok, Error = Self::Error>;
107
108    /// Always serialize this element with the given prefix.
109    fn include_prefix(&mut self, should_enforce: IncludePrefix) -> Result<Self::Ok, Self::Error>;
110
111    /// Set the preferred prefix for this element.
112    fn preferred_prefix(
113        &mut self,
114        preferred_prefix: Option<Prefix<'_>>,
115    ) -> Result<Self::Ok, Self::Error>;
116
117    /// Serialize the attributes of this element.
118    fn serialize_attributes(self) -> Result<Self::SerializeElementAttributes, Self::Error>;
119
120    /// Serialize the children of this element.
121    fn serialize_children(self) -> Result<Self::ChildrenSerializeSeq, Self::Error>;
122
123    /// End the serialization of this element with no children.
124    fn end(self) -> Result<Self::Ok, Self::Error>;
125}
126
127/// A trait for serializing a sequence of elements.
128#[must_use = "Serializers could be lazy and must be consumed to guarantee serialization. Try calling `.end()` on the serializer."]
129pub trait SerializeSeq {
130    /// The type of the value that is returned when serialization is successful.
131    type Ok;
132    /// The type of the error that is returned when serialization fails.
133    type Error: Error;
134
135    /// Serialize an element in the sequence.
136    fn serialize_element<V: Serialize>(&mut self, v: &V) -> Result<Self::Ok, Self::Error>;
137
138    /// End the serialization of the sequence.
139    fn end(self) -> Result<Self::Ok, Self::Error>;
140}
141
142/// A serializer receives serialization instructions from a [`Serialize`] implementation and produces serialized output.
143pub trait Serializer: Sized {
144    /// The type of the value that is returned when serialization is successful.
145    type Ok;
146    /// The type of the error that is returned when serialization fails.
147    type Error: Error;
148    /// The type of the serializer that is used to serialize an element with children.
149    type SerializeElement: SerializeElement<Ok = Self::Ok, Error = Self::Error>;
150    /// The type of the serializer that is used to serialize a sequence of elements.
151    type SerializeSeq: SerializeSeq<Ok = Self::Ok, Error = Self::Error>;
152
153    /// Serialize a text node.
154    fn serialize_text<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error>;
155
156    /// Serialize a CDATA section.
157    fn serialize_cdata<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error>;
158
159    /// Serialize an element with children.
160    fn serialize_element(
161        self,
162        name: &'_ ExpandedName<'_>,
163    ) -> Result<Self::SerializeElement, Self::Error>;
164
165    /// Serialize a sequence of elements.
166    fn serialize_seq(self) -> Result<Self::SerializeSeq, Self::Error>;
167
168    /// Serialize an XML declaration.
169    fn serialize_decl<S: AsRef<str>>(
170        self,
171        version: S,
172        encoding: Option<S>,
173        standalone: Option<S>,
174    ) -> Result<Self::Ok, Self::Error>;
175
176    /// Serialize a processing instruction.
177    fn serialize_pi<S: AsRef<[u8]>>(self, target: S, content: S) -> Result<Self::Ok, Self::Error>;
178
179    /// Serialize a comment.
180    fn serialize_comment<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error>;
181
182    /// Serialize a doctype declaration.
183    fn serialize_doctype<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error>;
184
185    /// Serialize nothing.
186    fn serialize_none(self) -> Result<Self::Ok, Self::Error>;
187}
188
189/// A type that can serialize attributes. Works in a similar way to [`Serializer`].
190pub trait AttributeSerializer: Sized {
191    /// The type of the value that is returned when serialization is successful.
192    type Ok;
193    /// The type of the error that is returned when serialization fails.
194    type Error: Error;
195    /// The type returned when serializing an attribute.
196    type SerializeAttribute<'a>: SerializeAttributeAccess<Ok = Self::Ok, Error = Self::Error>
197    where
198        Self: 'a;
199
200    /// Serialize an attribute.
201    fn serialize_attribute(
202        &mut self,
203        name: &'_ ExpandedName<'_>,
204    ) -> Result<Self::SerializeAttribute<'_>, Self::Error>;
205
206    /// Serialize nothing.
207    fn serialize_none(&mut self) -> Result<Self::Ok, Self::Error>;
208}
209
210/// 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.
211///
212/// To see the documentation for the derive macro, see [`xmlity_derive::Serialize`].
213pub trait Serialize {
214    /// Serialize the type.
215    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
216}
217
218impl<T: Serialize> Serialize for &T {
219    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
220        T::serialize(*self, serializer)
221    }
222}
223
224impl<T: Serialize> Serialize for &mut T {
225    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
226        T::serialize(*self, serializer)
227    }
228}
229
230/// Setting for whether to enforce a prefix when serializing.
231#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
232pub enum IncludePrefix {
233    /// Always enforce the prefix.
234    Always,
235    /// Only when the preferred prefix is not the used prefix.
236    WhenNecessaryForPreferredPrefix,
237    /// Only use the prefix when it is absolutely necessary.
238    #[default]
239    Never,
240}
241
242/// A type that can be used to serialize an attribute.
243pub trait SerializeAttributeAccess: Sized {
244    /// The type of the value that is returned when serialization is successful.
245    type Ok;
246    /// The type of the error that is returned when serialization fails.
247    type Error: Error;
248
249    /// Set whether to enforce a prefix when serializing.
250    fn include_prefix(&mut self, should_include: IncludePrefix) -> Result<Self::Ok, Self::Error>;
251
252    /// Set the preferred prefix to use when serializing.
253    fn preferred_prefix(
254        &mut self,
255        preferred_prefix: Option<Prefix<'_>>,
256    ) -> Result<Self::Ok, Self::Error>;
257
258    /// Serialize the attribute.
259    fn end<S: Serialize>(self, value: &S) -> Result<Self::Ok, Self::Error>;
260}
261
262/// 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.
263///
264/// To see the documentation for the derive macro, see [`xmlity_derive::SerializeAttribute`].
265pub trait SerializeAttribute: Sized {
266    /// Serialize the attribute.
267    fn serialize_attribute<S: AttributeSerializer>(&self, serializer: S)
268        -> Result<S::Ok, S::Error>;
269}
270
271/// 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.
272///
273/// To see the documentation for the derive macro, see [`xmlity_derive::SerializationGroup`].
274pub trait SerializationGroup: Sized {
275    /// Serialize the attributes of the type.
276    fn serialize_attributes<S: SerializeAttributes>(
277        &self,
278        serializer: &mut S,
279    ) -> Result<(), S::Error> {
280        let _ = serializer;
281
282        Ok(())
283    }
284
285    /// Serialize the children of the type.
286    fn serialize_children<S: SerializeSeq>(&self, serializer: &mut S) -> Result<(), S::Error> {
287        let _ = serializer;
288
289        Ok(())
290    }
291}
292
293impl<T: SerializationGroup> SerializationGroup for &T {
294    fn serialize_attributes<S: SerializeAttributes>(
295        &self,
296        serializer: &mut S,
297    ) -> Result<(), S::Error> {
298        T::serialize_attributes(*self, serializer)
299    }
300
301    fn serialize_children<S: SerializeSeq>(&self, serializer: &mut S) -> Result<(), S::Error> {
302        T::serialize_children(*self, serializer)
303    }
304}
305
306impl<T: SerializationGroup> SerializationGroup for &mut T {
307    fn serialize_attributes<S: SerializeAttributes>(
308        &self,
309        serializer: &mut S,
310    ) -> Result<(), S::Error> {
311        T::serialize_attributes(*self, serializer)
312    }
313
314    fn serialize_children<S: SerializeSeq>(&self, serializer: &mut S) -> Result<(), S::Error> {
315        T::serialize_children(*self, serializer)
316    }
317}