Skip to main content

deser_xml/
ser.rs

1use std::borrow::Cow;
2use std::fmt::Write as _;
3
4use deser_core::ext::Number;
5use deser_core::hints::Layout;
6use deser_core::ser::SerializeRef;
7use deser_core::ser::{self, Describe, EventSink, SerializeDriver};
8use deser_core::{Atom, BytesFormat, Error, ErrorKind, Event, Serialize, State};
9
10use crate::Names;
11use crate::de::XML_NAMESPACE;
12use crate::mixed::KeepsWhitespace;
13use crate::root::{Declarations, RootData};
14
15/// How the output is indented.
16///
17/// See [`SerializerConfig::set_indent`].
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
19#[non_exhaustive]
20pub enum Indent {
21    /// No indentation, the document is written on a single line.
22    #[default]
23    None,
24    /// Child elements on lines of their own, indented by the given number
25    /// of spaces per level.
26    Spaces(usize),
27    /// Child elements on lines of their own, indented by a tab per level.
28    Tab,
29}
30
31/// Configures how values are serialized to XML.
32///
33/// The value becomes the root element.  Its name is the one of the
34/// [`Root`](crate::Root) of the value (or of the document the value was
35/// read from, if it's a value that keeps event data like a
36/// [`Recording`](deser_core::de::Recording)), the name of the struct (or
37/// enum) that is serialized or the configured [`set_root`](Self::set_root).  Maps
38/// are elements: keys with the
39/// [attribute prefix](Self::set_attribute_prefix) are attributes, the
40/// [text key](Self::set_text_key) is text and all other keys are child
41/// elements.  Sequences are elements with the same name, one per value.
42/// Null values are left out.  Attributes can come after other keys, they
43/// are still written into the start tag.
44///
45/// Names can be `{uri}local` (the notation of James Clark, attributes are
46/// `@{uri}local`, see [`qname!`](crate::qname)): their namespace gets the
47/// [configured prefix](Self::namespaces) or a generated one (`ns0`, ...).
48/// Every namespace has one prefix in the document, all of them are
49/// declared on the root element.  Other names are written as they are.
50///
51/// ```
52/// #[derive(deser::Serialize)]
53/// struct Link {
54///     #[deser(rename = "@href")]
55///     href: String,
56///     #[deser(rename = "$text")]
57///     title: String,
58/// }
59///
60/// #[derive(deser::Serialize)]
61/// #[deser(rename = "feed")]
62/// struct Feed {
63///     link: Vec<Link>,
64///     updated: Option<String>,
65/// }
66///
67/// let feed = Feed {
68///     link: vec![Link { href: "/a".into(), title: "A & B".into() }],
69///     updated: None,
70/// };
71/// assert_eq!(
72///     deser_xml::to_string(&feed).unwrap(),
73///     r#"<feed><link href="/a">A &amp; B</link></feed>"#
74/// );
75/// ```
76///
77/// By default the output is a single line, [`set_indent`](Self::set_indent) writes
78/// child elements on lines of their own.
79#[derive(Debug, Clone, PartialEq, Eq)]
80pub struct SerializerConfig {
81    names: Names,
82    root: Option<&'static str>,
83    declaration: bool,
84    indent: Indent,
85    context: deser_core::Context,
86}
87
88impl Default for SerializerConfig {
89    fn default() -> SerializerConfig {
90        SerializerConfig::new()
91    }
92}
93
94impl SerializerConfig {
95    /// Creates the default configuration.
96    pub const fn new() -> SerializerConfig {
97        SerializerConfig {
98            names: Names::new(),
99            root: None,
100            declaration: false,
101            indent: Indent::None,
102            context: deser_core::Context::new(),
103        }
104    }
105
106    /// Returns a builder for the configuration (see [`SerializerConfigBuilder`]).
107    pub const fn builder() -> SerializerConfigBuilder {
108        SerializerConfigBuilder::new()
109    }
110
111    /// Returns a builder that starts with this configuration.
112    pub const fn into_builder(self) -> SerializerConfigBuilder {
113        SerializerConfigBuilder { value: self }
114    }
115
116    /// Sets the context the values are serialized in.
117    ///
118    /// The values of the context are the defaults of the extension values
119    /// of the state (see [`Context`](deser_core::Context)), for instance
120    /// the [`BytesFormat`](deser_core::BytesFormat).  The serializers and
121    /// writers created with the configuration use this context.  A context set on
122    /// the driver takes precedence.
123    pub fn set_context(&mut self, context: deser_core::Context) {
124        self.context = context;
125    }
126
127    /// Returns the context the values are serialized in.
128    pub fn context(&self) -> &deser_core::Context {
129        &self.context
130    }
131
132    /// Gives the context to a driver which has none.
133    #[inline]
134    fn apply_context(&self, driver: &mut SerializeDriver<'_>) {
135        if !self.context.is_empty() {
136            driver.set_default_context(self.context.clone());
137        }
138    }
139
140    /// Sets the name of the root element of values without a name.
141    ///
142    /// The root element is named after the [`Root`](crate::Root) of the
143    /// value or the struct or enum that is serialized.  Other values (like
144    /// maps) are named with this.  This is useful where values cannot be
145    /// wrapped in a `Root`, for instance when transcoding from another
146    /// format.
147    pub const fn set_root(&mut self, name: &'static str) {
148        self.root = Some(name);
149    }
150
151    /// Sets the prefix of the keys that are attributes (default `@`).
152    pub const fn set_attribute_prefix(&mut self, prefix: &'static str) {
153        self.names.attribute_prefix = prefix;
154    }
155
156    /// Sets the key that is the text of an element (default `$text`).
157    pub const fn set_text_key(&mut self, key: &'static str) {
158        self.names.text_key = key;
159    }
160
161    /// Sets the prefixes of namespaces that are declared on the root
162    /// element.
163    ///
164    /// The namespaces of the [`Root`](crate::Root) of the value come first,
165    /// configured namespaces whose prefix they use are left out.  The empty
166    /// prefix declares the default namespace.  Names that are
167    /// `{uri}local` are written with these prefixes, attributes only with
168    /// prefixes that are not empty.  Namespaces without prefix get
169    /// generated ones.  The table can be written with
170    /// [`prefixes!`](crate::prefixes).
171    ///
172    /// ```
173    /// use deser_xml::SerializerConfig;
174    ///
175    /// deser_xml::namespace!(
176    ///     atom = "http://www.w3.org/2005/Atom",
177    ///     dc = "http://purl.org/dc/elements/1.1/",
178    ///     media = "http://search.yahoo.com/mrss/",
179    /// );
180    ///
181    /// #[derive(deser::Serialize)]
182    /// #[deser(rename = atom!("feed"))]
183    /// struct Feed {
184    ///     #[deser(rename = atom!("title"))]
185    ///     title: String,
186    ///     #[deser(rename = dc!("creator"))]
187    ///     creator: Vec<String>,
188    ///     #[deser(rename = media!("thumbnail"))]
189    ///     thumbnail: String,
190    /// }
191    ///
192    /// const CONFIG: SerializerConfig = SerializerConfig::new()
193    ///     .namespaces(deser_xml::prefixes![atom as "", dc]);
194    /// let feed = Feed {
195    ///     title: "x".into(),
196    ///     creator: vec!["y".into(), "z".into()],
197    ///     thumbnail: "t.png".into(),
198    /// };
199    /// assert_eq!(
200    ///     CONFIG.to_string(&feed).unwrap(),
201    ///     "<feed xmlns=\"http://www.w3.org/2005/Atom\" \
202    ///      xmlns:dc=\"http://purl.org/dc/elements/1.1/\" \
203    ///      xmlns:ns0=\"http://search.yahoo.com/mrss/\"><title>x</title>\
204    ///      <dc:creator>y</dc:creator><dc:creator>z</dc:creator>\
205    ///      <ns0:thumbnail>t.png</ns0:thumbnail></feed>"
206    /// );
207    /// ```
208    pub const fn namespaces(
209        mut self,
210        namespaces: &'static [(&'static str, &'static str)],
211    ) -> SerializerConfig {
212        self.names.namespaces = namespaces;
213        self
214    }
215
216    /// Sets if the XML declaration is written (default `false`).
217    pub const fn set_declaration(&mut self, yes: bool) {
218        self.declaration = yes;
219    }
220
221    /// Sets how the output is indented.
222    ///
223    /// By default ([`Indent::None`]) the document is written on a single
224    /// line.  Otherwise the child elements of an element are written on
225    /// lines of their own, indented by their depth, and the end tag on a
226    /// line of its own:
227    ///
228    /// ```
229    /// use deser_xml::{Indent, SerializerConfig};
230    ///
231    /// #[derive(deser::Serialize)]
232    /// #[deser(rename = "point")]
233    /// struct Point {
234    ///     #[deser(rename = "@id")]
235    ///     id: u32,
236    ///     x: i32,
237    ///     y: i32,
238    /// }
239    ///
240    /// const PRETTY: SerializerConfig =
241    ///     SerializerConfig::builder().indent(Indent::Spaces(2)).build();
242    /// assert_eq!(
243    ///     PRETTY.to_string(&Point { id: 1, x: 3, y: 4 }).unwrap(),
244    ///     "<point id=\"1\">\n  <x>3</x>\n  <y>4</y>\n</point>"
245    /// );
246    /// ```
247    ///
248    /// Unlike in JSON whitespace can be text in XML.  It is only added
249    /// between tags where it's not text of the elements (the deserializer
250    /// skips it), elements with text are written on a single line:
251    ///
252    /// * The text of elements is never changed, elements with text and
253    ///   child elements (mixed content like `<p>x <b>y</b></p>`) are
254    ///   written on a single line from the text on.  If the element is a
255    ///   struct whose [text key](Self::set_text_key) field comes after the
256    ///   child element, the element is written on a single line from the
257    ///   start (unless it has [`Layout::Expanded`]).
258    /// * [`Mixed`](crate::Mixed) keeps whitespace as text by default, its
259    ///   content is written on a single line.
260    /// * Elements and sequences with [`Layout::Compact`] (see
261    ///   [`hints`](deser_core::hints)) are written on a single line, also
262    ///   their content.
263    ///
264    /// With the [declaration](Self::set_declaration) the root element starts on
265    /// a new line.  The output never ends with a line break.
266    pub const fn set_indent(&mut self, indent: Indent) {
267        self.indent = indent;
268    }
269
270    /// Enables or disables pretty printing.
271    ///
272    /// This is the same as [`set_indent`](Self::set_indent), XML has no
273    /// spaces after separators like JSON.
274    ///
275    /// ```
276    /// use std::collections::BTreeMap;
277    /// use deser_xml::{Indent, SerializerConfig};
278    ///
279    /// let value = BTreeMap::from([("a", 1), ("b", 2)]);
280    /// const PRETTY: SerializerConfig =
281    ///     SerializerConfig::builder().root("r").pretty(Indent::Tab).build();
282    /// assert_eq!(
283    ///     PRETTY.to_string(&value).unwrap(),
284    ///     "<r>\n\t<a>1</a>\n\t<b>2</b>\n</r>"
285    /// );
286    /// ```
287    pub const fn set_pretty(&mut self, indent: Indent) {
288        self.set_indent(indent);
289    }
290
291    /// Serializes a value.
292    pub fn to_string<T: Serialize + ?Sized>(&self, value: &T) -> Result<String, Error> {
293        self.to_string_ref(SerializeRef::new(&value))
294    }
295
296    /// Serializes a value with a configured driver.
297    ///
298    /// The callback is invoked with the driver before the serialization
299    /// starts, for instance to add [`Layer`](deser_core::ser::Layer)s.
300    pub fn to_string_with<F, T: Serialize + ?Sized>(
301        &self,
302        value: &T,
303        setup: F,
304    ) -> Result<String, Error>
305    where
306        F: FnOnce(&mut SerializeDriver<'_>),
307    {
308        let mut driver = SerializeDriver::new(&value);
309        setup(&mut driver);
310        self.apply_context(&mut driver);
311        self.serialize_driver(&mut driver)
312    }
313
314    /// Serializes a value whose type is erased (see
315    /// [`to_string`](Self::to_string)).
316    ///
317    /// This is not generic: the code that exists for every type only
318    /// erases it.
319    fn to_string_ref(&self, value: SerializeRef<'_>) -> Result<String, Error> {
320        let mut driver = SerializeDriver::from_ref(value);
321        self.apply_context(&mut driver);
322        self.serialize_driver(&mut driver)
323    }
324
325    /// Serializes the value of a driver into a document.
326    fn serialize_driver(&self, driver: &mut SerializeDriver<'_>) -> Result<String, Error> {
327        let mut writer = Writer::new(self, BytesFormat::of(driver.state()));
328        driver.drive_sink(&mut writer)?;
329        writer.finish()?;
330        Ok(writer.out)
331    }
332
333    /// Serializes (a part of) the value of a driver and appends the output
334    /// that is final.
335    ///
336    /// The progress of the value is kept in `value` (see
337    /// `StreamSerializer::drive_partial`), `true` is returned once the
338    /// value is complete.  The output of a value is final once its start
339    /// tag is complete, which is the case once no more attributes can come
340    /// for the element (see `final_until`).  Output is only appended if
341    /// this succeeds.
342    pub(crate) fn serialize_part(
343        &self,
344        value: &mut Option<Box<Writer>>,
345        driver: &mut SerializeDriver<'_>,
346        out: &mut String,
347        limit: usize,
348    ) -> Result<bool, Error> {
349        // a document that is written at once does not box the writer
350        if value.is_none() && limit == usize::MAX {
351            let document = self.serialize_driver(driver)?;
352            if out.is_empty() {
353                *out = document;
354            } else {
355                out.push_str(&document);
356            }
357            return Ok(true);
358        }
359        let mut writer = value
360            .take()
361            .unwrap_or_else(|| Box::new(Writer::new(self, BytesFormat::of(driver.state()))));
362        // after an error the value is abandoned, its writer is dropped
363        let done = if limit == usize::MAX {
364            driver.drive_sink(&mut *writer)?;
365            true
366        } else {
367            writer.limit = limit;
368            driver.drive_until(&mut *writer)?
369        };
370        if let Some(err) = writer.error.take() {
371            return Err(err);
372        }
373        if done {
374            writer.finish()?;
375            out.push_str(&writer.out);
376            return Ok(true);
377        }
378        writer.pass_on(out);
379        *value = Some(writer);
380        Ok(false)
381    }
382}
383
384/// Builds a [`SerializerConfig`].
385///
386/// The methods have the names of the setters of [`SerializerConfig`] (without `set_`).
387#[derive(Debug, Clone)]
388#[must_use]
389pub struct SerializerConfigBuilder {
390    value: SerializerConfig,
391}
392
393impl SerializerConfigBuilder {
394    /// Creates a builder that starts with the default.
395    pub const fn new() -> SerializerConfigBuilder {
396        SerializerConfigBuilder {
397            value: SerializerConfig::new(),
398        }
399    }
400
401    /// Sets the name of the root element of values without a name.
402    ///
403    /// See [`SerializerConfig::set_root`].
404    pub const fn root(mut self, name: &'static str) -> SerializerConfigBuilder {
405        self.value.set_root(name);
406        self
407    }
408
409    /// Sets the prefix of the keys that are attributes (default `@`).
410    ///
411    /// See [`SerializerConfig::set_attribute_prefix`].
412    pub const fn attribute_prefix(mut self, prefix: &'static str) -> SerializerConfigBuilder {
413        self.value.set_attribute_prefix(prefix);
414        self
415    }
416
417    /// Sets the key that is the text of an element (default `$text`).
418    ///
419    /// See [`SerializerConfig::set_text_key`].
420    pub const fn text_key(mut self, key: &'static str) -> SerializerConfigBuilder {
421        self.value.set_text_key(key);
422        self
423    }
424
425    /// Sets if the XML declaration is written (default `false`).
426    ///
427    /// See [`SerializerConfig::set_declaration`].
428    pub const fn declaration(mut self, yes: bool) -> SerializerConfigBuilder {
429        self.value.set_declaration(yes);
430        self
431    }
432
433    /// Sets how the output is indented.
434    ///
435    /// See [`SerializerConfig::set_indent`].
436    pub const fn indent(mut self, indent: Indent) -> SerializerConfigBuilder {
437        self.value.set_indent(indent);
438        self
439    }
440
441    /// Enables or disables pretty printing.
442    ///
443    /// See [`SerializerConfig::set_pretty`].
444    pub const fn pretty(mut self, indent: Indent) -> SerializerConfigBuilder {
445        self.value.set_pretty(indent);
446        self
447    }
448
449    /// Sets the context the values are serialized in.
450    ///
451    /// See [`SerializerConfig::set_context`].
452    pub fn context(mut self, context: deser_core::Context) -> SerializerConfigBuilder {
453        self.value.set_context(context);
454        self
455    }
456
457    /// Returns the built [`SerializerConfig`].
458    pub const fn build(self) -> SerializerConfig {
459        // the value cannot be moved out of the builder in a const fn as the
460        // builder needs dropping (the context has a destructor)
461        // SAFETY: the value is read once and the builder is forgotten
462        let value = unsafe { core::ptr::read(&self.value) };
463        core::mem::forget(self);
464        value
465    }
466}
467
468impl Default for SerializerConfigBuilder {
469    fn default() -> SerializerConfigBuilder {
470        SerializerConfigBuilder::new()
471    }
472}
473
474/// Serializes values to XML.
475///
476/// This is the XML implementation of the [`Serializer`](ser::Serializer)
477/// trait, which allows serializing to XML where the format is not known
478/// upfront.  For a value that is serialized once
479/// [`SerializerConfig::to_string`] (or [`to_string`]) is simpler.
480///
481/// An XML document has a single root element, serializing a second value
482/// fails.  Values without a name (like maps) need a [`Root`](crate::Root)
483/// or the name of the root element in the configuration (see
484/// [`SerializerConfig::set_root`]).
485///
486/// ```
487/// use std::collections::BTreeMap;
488/// use deser_xml::{Serializer, SerializerConfig};
489///
490/// let mut serializer = Serializer::with_config(SerializerConfig::builder().root("r").build());
491/// serializer.serialize(&BTreeMap::from([("@a", 1), ("b", 2)])).unwrap();
492/// assert!(serializer.serialize(&BTreeMap::from([("b", 3)])).is_err());
493/// assert_eq!(serializer.finish(), r#"<r a="1"><b>2</b></r>"#);
494/// ```
495///
496/// The serializer is also the stream serializer of XML (see
497/// [`StreamSerializer`](ser::StreamSerializer)): the output can be taken
498/// while the document is written, and large documents can be written in
499/// parts.  Output is final once the start tag it's in is complete: the
500/// start tag of an element is held back until no more attributes can come,
501/// which for maps (whose keys are not known upfront) is the end of the
502/// element.  The namespaces that are found once the start tag of the root
503/// element was written are declared on the elements that use them rather
504/// than on the root element (configured
505/// [namespaces](SerializerConfig::namespaces) are always declared on the
506/// root element).  To write to a [`Write`](std::io::Write) use
507/// [`SerializerConfig::writer`].
508pub struct Serializer {
509    config: SerializerConfig,
510    out: String,
511    written: bool,
512    // the document that is written in parts
513    document: Option<Box<Writer>>,
514    // a document was started with `drive_partial` and is not complete
515    in_progress: bool,
516}
517
518impl Default for Serializer {
519    fn default() -> Serializer {
520        Serializer::new()
521    }
522}
523
524impl Clone for Serializer {
525    /// Clones the serializer.
526    ///
527    /// The clone of a serializer that writes a document in parts cannot
528    /// write more values (see
529    /// [`StreamSerializer::in_progress`](ser::StreamSerializer::in_progress)).
530    fn clone(&self) -> Serializer {
531        Serializer {
532            config: self.config.clone(),
533            out: self.out.clone(),
534            written: self.written,
535            document: None,
536            in_progress: self.in_progress,
537        }
538    }
539}
540
541impl std::fmt::Debug for Serializer {
542    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
543        f.debug_struct("Serializer")
544            .field("config", &self.config)
545            .field("output", &self.out)
546            .field("written", &self.written)
547            .field("in_progress", &self.in_progress)
548            .finish()
549    }
550}
551
552impl Serializer {
553    /// Creates a serializer.
554    pub fn new() -> Serializer {
555        Serializer::with_config(SerializerConfig::new())
556    }
557
558    /// Creates a serializer with the given configuration.
559    pub fn with_config(config: SerializerConfig) -> Serializer {
560        Serializer {
561            config,
562            out: String::new(),
563            written: false,
564            document: None,
565            in_progress: false,
566        }
567    }
568
569    /// Returns the configuration.
570    pub fn config(&self) -> &SerializerConfig {
571        &self.config
572    }
573
574    /// Returns `true` once the document was written.
575    pub fn written(&self) -> bool {
576        self.written
577    }
578
579    /// Serializes a value.
580    ///
581    /// If the value fails to serialize, nothing is written.
582    pub fn serialize<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
583        ser::Serializer::serialize(self, value)
584    }
585
586    /// Serializes a value with a configured driver.
587    ///
588    /// The callback is invoked with the driver before the value is
589    /// serialized, for instance to add [`Layer`](deser_core::ser::Layer)s.
590    pub fn serialize_with<F, T: Serialize + ?Sized>(
591        &mut self,
592        value: &T,
593        setup: F,
594    ) -> Result<(), Error>
595    where
596        F: FnOnce(&mut SerializeDriver<'_>),
597    {
598        ser::Serializer::serialize_with(self, value, setup)
599    }
600
601    /// Returns the output written so far (that was not cleared).
602    pub fn as_str(&self) -> &str {
603        &self.out
604    }
605
606    /// Returns the output.
607    pub fn finish(self) -> String {
608        self.out
609    }
610}
611
612impl ser::Serializer for Serializer {
613    fn drive(&mut self, driver: &mut SerializeDriver<'_>) -> Result<(), Error> {
614        // only `drive_partial` continues a document
615        if self.in_progress {
616            return Err(Error::in_progress());
617        }
618        ser::StreamSerializer::drive_partial(self, driver, usize::MAX).map(|_| ())
619    }
620}
621
622impl ser::StreamSerializer for Serializer {
623    fn output(&self) -> &[u8] {
624        self.out.as_bytes()
625    }
626
627    fn clear_output(&mut self) {
628        self.out.clear();
629    }
630
631    fn supports_partial(&self) -> bool {
632        true
633    }
634
635    fn drive_partial(
636        &mut self,
637        driver: &mut SerializeDriver<'_>,
638        limit: usize,
639    ) -> Result<bool, Error> {
640        if !self.config.context.is_empty() {
641            driver.set_default_context(self.config.context.clone());
642        }
643        if self.document.is_none() {
644            if self.in_progress {
645                return Err(Error::in_progress());
646            }
647            if self.written {
648                return Err(Error::new(
649                    ErrorKind::InvalidState,
650                    "an XML document holds a single root element",
651                ));
652            }
653        }
654        // the parts of a document that failed stay written (see
655        // `in_progress`)
656        if !self
657            .config
658            .serialize_part(&mut self.document, driver, &mut self.out, limit)?
659        {
660            self.in_progress = true;
661            return Ok(false);
662        }
663        self.in_progress = false;
664        self.written = true;
665        Ok(true)
666    }
667
668    fn in_progress(&self) -> bool {
669        self.in_progress
670    }
671}
672
673#[cfg(feature = "io")]
674impl SerializerConfig {
675    /// Creates a writer of an XML document (see
676    /// [`deser::io::Writer`](deser_core::io::Writer)).
677    ///
678    /// A stream holds a single document, writing a second value fails.  The
679    /// document is written in parts while the value is serialized (see
680    /// [`Serializer`]).
681    ///
682    /// ```
683    /// use deser_xml::SerializerConfig;
684    ///
685    /// #[derive(deser::Serialize)]
686    /// #[deser(rename = "feed")]
687    /// struct Feed {
688    ///     entry: Vec<u32>,
689    /// }
690    ///
691    /// let mut writer = SerializerConfig::new().writer(Vec::new());
692    /// writer.set_buffer_limit(8);
693    /// writer.write(&Feed { entry: vec![1, 2, 3] }).unwrap();
694    /// assert_eq!(
695    ///     writer.into_inner(),
696    ///     b"<feed><entry>1</entry><entry>2</entry><entry>3</entry></feed>"
697    /// );
698    /// ```
699    pub fn writer<W: std::io::Write>(&self, writer: W) -> deser_core::io::Writer<W, Serializer> {
700        deser_core::io::Writer::new(writer, Serializer::with_config(self.clone()))
701    }
702
703    /// Serializes a value as XML document to a writer.
704    ///
705    /// See [`to_writer`].
706    pub fn to_writer<W: std::io::Write, T: Serialize + ?Sized>(
707        &self,
708        writer: W,
709        value: &T,
710    ) -> Result<(), Error> {
711        self.writer(writer).write(value)
712    }
713}
714
715/// Serializes a value as XML document to a writer.
716///
717/// The output is written in parts while the value is serialized (see
718/// [`Serializer`]), the writer does not need to be buffered.
719///
720/// ```
721/// #[derive(deser::Serialize)]
722/// #[deser(rename = "a")]
723/// struct Link {
724///     #[deser(rename = "@href")]
725///     href: String,
726/// }
727///
728/// let mut out = Vec::new();
729/// deser_xml::to_writer(&mut out, &Link { href: "/x".into() }).unwrap();
730/// assert_eq!(out, br#"<a href="/x"/>"#);
731/// ```
732#[cfg(feature = "io")]
733pub fn to_writer<W: std::io::Write, T: Serialize + ?Sized>(
734    writer: W,
735    value: &T,
736) -> Result<(), Error> {
737    SerializerConfig::new().to_writer(writer, value)
738}
739
740/// Serializes a value to XML with the default configuration.
741///
742/// See [`SerializerConfig`].
743pub fn to_string<T: Serialize + ?Sized>(value: &T) -> Result<String, Error> {
744    SerializerConfig::new().to_string(value)
745}
746
747/// An element or sequence that is being written.
748enum Frame {
749    Element(Element),
750    /// A sequence whose values are elements with the name.
751    Items {
752        name: String,
753        /// If the elements are written on a single line.
754        compact: bool,
755        /// If an element was written.
756        started: bool,
757    },
758}
759
760/// How the content of an element is laid out.
761#[derive(Clone, Copy, PartialEq, Eq)]
762enum Lines {
763    /// Not decided yet, no child element was written.
764    Pending,
765    /// Child elements are on lines of their own.
766    Indented,
767    /// Everything is on a single line from here on.
768    Inline,
769}
770
771/// An element whose content is a map.
772struct Element {
773    /// The name as written.
774    name: String,
775    /// Where attributes are added to the start tag (in the document).
776    attrs_at: usize,
777    /// If the start tag was ended because content was written.
778    content: bool,
779    /// Attributes that came after content, they are added to the start
780    /// tag once no more can come.
781    late: String,
782    /// Which attributes can still come.
783    attrs: Attrs,
784    /// The fields of the struct and the index after the last key among
785    /// them, `None` if the keys are not known.
786    fields: Option<(&'static [&'static str], usize)>,
787    /// The number of local namespace bindings outside of the element.
788    bindings: usize,
789    /// How the content is laid out.
790    lines: Lines,
791    /// If the layout is not predicted from the fields.
792    expanded: bool,
793}
794
795/// Which attributes an element can still get.
796///
797/// The output from the start tag of the first element that can still get
798/// attributes on is not final and cannot be passed on.
799enum Attrs {
800    /// Any, the keys of the map are not known.
801    Unknown,
802    /// Those among the fields of the struct (see `Element::fields`), the
803    /// field with the index is the last attribute.
804    Until(usize),
805    /// None.
806    Done,
807}
808
809/// What a key of a map stands for.
810enum Key {
811    /// An attribute, `last` if no other attribute can follow.
812    Attribute {
813        name: String,
814        last: bool,
815    },
816    Text,
817    Element(String),
818}
819
820/// Writes the events of a document.
821pub(crate) struct Writer {
822    config: SerializerConfig,
823    /// How bytes are written (from the state).
824    bytes: BytesFormat,
825    /// The output that was not passed on yet, it starts at `base` in the
826    /// document.
827    out: String,
828    base: usize,
829    /// The driver is paused once this much output is final (see
830    /// `EventSink`).
831    limit: usize,
832    /// An error of `pause`, which cannot fail.
833    error: Option<Error>,
834    stack: Vec<Frame>,
835    /// The key of the next value of the element on top of the stack.
836    key: Option<Key>,
837    /// The prefixes of the namespaces declared on the root element, the
838    /// first one is `xml` which is never declared.
839    root_bindings: Vec<(String, String)>,
840    /// If the declarations on the root element were written.  After that,
841    /// new namespaces are declared on the elements that use them.
842    root_declared: bool,
843    /// Where the declarations of the root element go (after its name).
844    root_declarations: Option<usize>,
845    /// The prefixes declared on the elements on the stack.
846    local_bindings: Vec<(String, String)>,
847    /// The number of elements on the stack.
848    depth: usize,
849}
850
851/// Finds the name of a type.
852#[derive(Default)]
853struct TypeName(Option<String>);
854
855impl Describe for TypeName {
856    fn structure(&mut self, name: &str) {
857        self.0.get_or_insert_with(|| name.to_string());
858    }
859
860    fn newtype(&mut self, name: &str) {
861        self.0.get_or_insert_with(|| name.to_string());
862    }
863
864    fn tuple_struct(&mut self, name: &str) {
865        self.0.get_or_insert_with(|| name.to_string());
866    }
867
868    fn unit_struct(&mut self, name: &str) {
869        self.0.get_or_insert_with(|| name.to_string());
870    }
871}
872
873/// Finds the fields of a struct that is a map.
874///
875/// Values that are variants are not the struct they describe last (for
876/// instance the content of an externally tagged variant is in a map with
877/// the name of the variant).
878#[derive(Default)]
879struct Fields {
880    names: Option<&'static [&'static str]>,
881    variant: bool,
882}
883
884impl Describe for Fields {
885    fn structure(&mut self, _name: &str) {
886        self.names = None;
887    }
888
889    fn fields(&mut self, names: &'static [&'static str]) {
890        self.names = Some(names);
891    }
892
893    fn variant(&mut self, _variant: &deser_core::ser::Variant<'_>) {
894        self.variant = true;
895    }
896}
897
898impl EventSink for Writer {
899    const DESCRIBED: bool = true;
900
901    fn event(
902        &mut self,
903        event: Event<'_>,
904        value: SerializeRef<'_>,
905        state: &mut State,
906    ) -> Result<(), Error> {
907        Writer::event(self, event, value, state)
908    }
909
910    fn pause(&mut self) -> bool {
911        // the declarations of the root element are only written once the
912        // output is passed on, as namespaces found afterwards are declared
913        // on the elements that use them
914        if self.final_until() - self.base < self.limit {
915            return false;
916        }
917        if let Err(err) = self.final_len() {
918            // the error is returned once the driver stopped
919            self.error = Some(err);
920        }
921        true
922    }
923}
924
925impl Writer {
926    fn new(config: &SerializerConfig, bytes: BytesFormat) -> Writer {
927        let mut out = String::new();
928        if config.declaration {
929            out.push_str("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
930            if config.indent != Indent::None {
931                out.push('\n');
932            }
933        }
934        Writer {
935            config: config.clone(),
936            bytes,
937            out,
938            base: 0,
939            limit: usize::MAX,
940            error: None,
941            stack: Vec::new(),
942            key: None,
943            root_bindings: std::iter::once(("xml", XML_NAMESPACE))
944                .chain(config.names.namespaces.iter().copied())
945                .map(|(prefix, uri)| (prefix.to_string(), uri.to_string()))
946                .collect(),
947            root_declared: false,
948            root_declarations: None,
949            local_bindings: Vec::new(),
950            depth: 0,
951        }
952    }
953
954    fn event(
955        &mut self,
956        event: Event<'_>,
957        value: SerializeRef<'_>,
958        state: &State,
959    ) -> Result<(), Error> {
960        match self.stack.last_mut() {
961            None => self.root(event, value, state)?,
962            Some(Frame::Items { .. }) => self.item(event, value, state)?,
963            Some(Frame::Element(element)) => match self.key.take() {
964                None => {
965                    // flattened mixed content marks the key of its first
966                    // entry
967                    if matches!(event, Event::Atom(_)) && keeps_whitespace(state) {
968                        element.lines = Lines::Inline;
969                    }
970                    self.key(event)?
971                }
972                Some(key) => self.entry(key, event, value, state)?,
973            },
974        }
975        Ok(())
976    }
977
978    fn root(
979        &mut self,
980        event: Event<'_>,
981        value: SerializeRef<'_>,
982        state: &State,
983    ) -> Result<(), Error> {
984        // the name and the namespaces of a `Root` or of the root element the
985        // value was read from come first, then the name of the type and the
986        // configured name
987        let root = state.event::<RootData>();
988        if let Some(root) = root {
989            self.bind_root(&root.namespaces)?;
990        }
991        let name = match root.and_then(|root| root.name.clone()) {
992            Some(name) => name,
993            None => {
994                let mut name = TypeName::default();
995                value.describe(&mut name);
996                name.0
997                    .or_else(|| self.config.root.map(str::to_string))
998                    .ok_or_else(|| {
999                        Error::new(
1000                            ErrorKind::UnsupportedType,
1001                            "the name of the root element is unknown (see deser_xml::Root)",
1002                        )
1003                    })?
1004            }
1005        };
1006        check_element_name(&name)?;
1007        match event {
1008            Event::MapStart(_) => self.open_element(&name, value, state),
1009            Event::Atom(atom) => self.atom_element(&name, &atom, true, state),
1010            _ => Err(Error::new(
1011                ErrorKind::UnsupportedType,
1012                "the root element must be a map or a single value",
1013            )),
1014        }
1015    }
1016
1017    /// Declares the namespaces of the root value on the root element.
1018    ///
1019    /// They come before the configured ones, which are left out if they
1020    /// have the same prefix.
1021    fn bind_root(&mut self, namespaces: &[(String, String)]) -> Result<(), Error> {
1022        let mut bindings = vec![self.root_bindings[0].clone()];
1023        for (prefix, uri) in namespaces {
1024            check_prefix(prefix)?;
1025            if !bindings.iter().any(|(x, _)| x == prefix) {
1026                bindings.push((prefix.clone(), uri.clone()));
1027            }
1028        }
1029        for binding in self.root_bindings.drain(1..) {
1030            if !bindings.iter().any(|(x, _)| *x == binding.0) {
1031                bindings.push(binding);
1032            }
1033        }
1034        self.root_bindings = bindings;
1035        Ok(())
1036    }
1037
1038    fn key(&mut self, event: Event<'_>) -> Result<(), Error> {
1039        let key = match event {
1040            Event::MapEnd => return self.close_element(),
1041            Event::Atom(ref atom) => match self.text(atom)? {
1042                Some(key) => key.into_owned(),
1043                None => return Err(unsupported_key()),
1044            },
1045            _ => return Err(unsupported_key()),
1046        };
1047
1048        // keep track of the attributes that can still come
1049        let Some(Frame::Element(element)) = self.stack.last_mut() else {
1050            unreachable!()
1051        };
1052        let mut is_last = false;
1053        if let Some((names, cursor)) = &mut element.fields {
1054            match names[*cursor..].iter().position(|name| *name == key) {
1055                Some(offset) => {
1056                    *cursor += offset + 1;
1057                    if let Attrs::Until(last) = element.attrs {
1058                        is_last = *cursor == last + 1;
1059                        if *cursor > last + 1 {
1060                            element.attrs = Attrs::Done;
1061                        }
1062                    }
1063                }
1064                // not a field, all bets are off
1065                None => {
1066                    element.fields = None;
1067                    if matches!(element.attrs, Attrs::Until(_)) {
1068                        element.attrs = Attrs::Unknown;
1069                    }
1070                }
1071            }
1072        }
1073
1074        let names = &self.config.names;
1075        self.key = Some(if key == names.text_key {
1076            Key::Text
1077        } else if let Some(name) = attribute_name(names, &key) {
1078            check_element_name(name)?;
1079            Key::Attribute {
1080                name: name.to_string(),
1081                last: is_last,
1082            }
1083        } else {
1084            check_element_name(&key)?;
1085            Key::Element(key)
1086        });
1087        self.settle();
1088        Ok(())
1089    }
1090
1091    fn entry(
1092        &mut self,
1093        key: Key,
1094        event: Event<'_>,
1095        value: SerializeRef<'_>,
1096        state: &State,
1097    ) -> Result<(), Error> {
1098        match (key, event) {
1099            (Key::Attribute { name, last }, Event::Atom(atom)) => {
1100                if let Some(text) = self.text(&atom)? {
1101                    let text = text.into_owned();
1102                    self.attribute(&name, &text)?;
1103                }
1104                if last && let Some(Frame::Element(element)) = self.stack.last_mut() {
1105                    element.attrs = Attrs::Done;
1106                    self.settle();
1107                }
1108                Ok(())
1109            }
1110            (Key::Text, Event::Atom(atom)) => {
1111                if let Some(text) = self.text(&atom)? {
1112                    let text = text.into_owned();
1113                    self.close_start_tag();
1114                    if !text.is_empty() {
1115                        // whitespace next to text would be text
1116                        let Some(Frame::Element(element)) = self.stack.last_mut() else {
1117                            unreachable!()
1118                        };
1119                        element.lines = Lines::Inline;
1120                    }
1121                    escape(&text, false, &mut self.out)?;
1122                }
1123                Ok(())
1124            }
1125            (Key::Element(name), Event::Atom(atom)) => {
1126                self.atom_element(&name, &atom, false, state)
1127            }
1128            (Key::Element(name), Event::MapStart(_)) => {
1129                self.before_child();
1130                self.open_element(&name, value, state)
1131            }
1132            (Key::Element(name), Event::SeqStart(_)) => {
1133                self.stack.push(Frame::Items {
1134                    name,
1135                    compact: Layout::of(state) == Layout::Compact,
1136                    started: false,
1137                });
1138                Ok(())
1139            }
1140            (Key::Attribute { name, .. }, _) => Err(Error::new(
1141                ErrorKind::UnsupportedType,
1142                format!("attribute `{name}` must be a single value"),
1143            )),
1144            (Key::Text, _) => Err(Error::new(
1145                ErrorKind::UnsupportedType,
1146                "the text of an element must be a single value",
1147            )),
1148            (Key::Element(_), _) => unreachable!("ends are handled by the frames"),
1149        }
1150    }
1151
1152    fn item(
1153        &mut self,
1154        event: Event<'_>,
1155        value: SerializeRef<'_>,
1156        state: &State,
1157    ) -> Result<(), Error> {
1158        let Some(Frame::Items { name, .. }) = self.stack.last() else {
1159            unreachable!()
1160        };
1161        let name = name.clone();
1162        match event {
1163            Event::SeqEnd => {
1164                self.stack.pop();
1165                Ok(())
1166            }
1167            // nulls keep their position
1168            Event::Atom(Atom::Null) => {
1169                self.before_child();
1170                let bindings = self.local_bindings.len();
1171                self.start_tag(&name, false, state)?;
1172                self.out.push_str("/>");
1173                self.local_bindings.truncate(bindings);
1174                Ok(())
1175            }
1176            Event::Atom(atom) => self.atom_element(&name, &atom, false, state),
1177            Event::MapStart(_) => {
1178                self.before_child();
1179                self.open_element(&name, value, state)
1180            }
1181            _ => Err(Error::new(
1182                ErrorKind::UnsupportedType,
1183                "sequences in sequences are not supported",
1184            )),
1185        }
1186    }
1187
1188    /// Writes an attribute of the element on top of the stack.
1189    fn attribute(&mut self, name: &str, value: &str) -> Result<(), Error> {
1190        let mut declarations = String::new();
1191        let name = self.qualify(name, true, &mut declarations)?;
1192        let Some(Frame::Element(element)) = self.stack.last_mut() else {
1193            unreachable!()
1194        };
1195        let out = if !element.content {
1196            &mut self.out
1197        } else if element.attrs_at >= self.base {
1198            &mut element.late
1199        } else {
1200            return Err(Error::new(
1201                ErrorKind::InvalidValue,
1202                format!(
1203                    "attribute `{name}` comes after the start tag of the element was written \
1204                     (the fields the value described are not the keys it has)"
1205                ),
1206            ));
1207        };
1208        out.push_str(&declarations);
1209        out.push(' ');
1210        out.push_str(&name);
1211        out.push_str("=\"");
1212        escape(value, true, out)?;
1213        out.push('"');
1214        if !element.content {
1215            element.attrs_at = self.base + self.out.len();
1216        }
1217        self.settle();
1218        Ok(())
1219    }
1220
1221    /// Adds the late attributes of the element on top of the stack to its
1222    /// start tag once no more attributes can come.
1223    fn settle(&mut self) {
1224        let Some(Frame::Element(element)) = self.stack.last_mut() else {
1225            return;
1226        };
1227        if !matches!(element.attrs, Attrs::Done) || element.late.is_empty() {
1228            return;
1229        }
1230        let late = std::mem::take(&mut element.late);
1231        let at = element.attrs_at;
1232        self.insert(at, &late);
1233    }
1234
1235    /// Inserts text into the output which was not passed on yet.
1236    ///
1237    /// Positions of attributes at or after the text move behind it.
1238    fn insert(&mut self, at: usize, text: &str) {
1239        self.out.insert_str(at - self.base, text);
1240        for frame in &mut self.stack {
1241            if let Frame::Element(element) = frame
1242                && element.attrs_at >= at
1243            {
1244                element.attrs_at += text.len();
1245            }
1246        }
1247    }
1248
1249    /// Writes an element whose content is a single value.
1250    ///
1251    /// Nulls are left out unless they are the root.
1252    fn atom_element(
1253        &mut self,
1254        name: &str,
1255        atom: &Atom<'_>,
1256        is_root: bool,
1257        state: &State,
1258    ) -> Result<(), Error> {
1259        let text = match self.text(atom)? {
1260            Some(text) => text.into_owned(),
1261            None if is_root => String::new(),
1262            None => return Ok(()),
1263        };
1264        self.before_child();
1265        let bindings = self.local_bindings.len();
1266        let name = self.start_tag(name, is_root, state)?;
1267        if text.is_empty() {
1268            self.out.push_str("/>");
1269        } else {
1270            self.out.push('>');
1271            escape(&text, false, &mut self.out)?;
1272            write!(self.out, "</{name}>").unwrap();
1273        }
1274        self.local_bindings.truncate(bindings);
1275        Ok(())
1276    }
1277
1278    /// Writes the start tag of an element whose content is a map.
1279    fn open_element(
1280        &mut self,
1281        name: &str,
1282        value: SerializeRef<'_>,
1283        state: &State,
1284    ) -> Result<(), Error> {
1285        let bindings = self.local_bindings.len();
1286        let name = self.start_tag(name, self.stack.is_empty(), state)?;
1287        let (fields, attrs) = self.fields_of(value);
1288        let layout = Layout::of(state);
1289        let lines = if self.config.indent == Indent::None
1290            || self.in_line()
1291            || layout == Layout::Compact
1292            || keeps_whitespace(state)
1293        {
1294            Lines::Inline
1295        } else {
1296            Lines::Pending
1297        };
1298        self.stack.push(Frame::Element(Element {
1299            name,
1300            attrs_at: self.base + self.out.len(),
1301            content: false,
1302            late: String::new(),
1303            attrs,
1304            fields: fields.map(|names| (names, 0)),
1305            bindings,
1306            lines,
1307            expanded: layout == Layout::Expanded,
1308        }));
1309        self.depth += 1;
1310        Ok(())
1311    }
1312
1313    /// Returns the fields of the map of a value and which attributes it
1314    /// can have.
1315    fn fields_of(&self, value: SerializeRef<'_>) -> (Option<&'static [&'static str]>, Attrs) {
1316        let mut fields = Fields::default();
1317        value.describe(&mut fields);
1318        let Some(names) = fields.names.filter(|_| !fields.variant) else {
1319            return (None, Attrs::Unknown);
1320        };
1321        let names_config = &self.config.names;
1322        let last = names.iter().rposition(|name| {
1323            *name != names_config.text_key && attribute_name(names_config, name).is_some()
1324        });
1325        let attrs = match last {
1326            Some(last) => Attrs::Until(last),
1327            None => Attrs::Done,
1328        };
1329        (Some(names), attrs)
1330    }
1331
1332    /// Returns `true` if the next element is written on a single line with
1333    /// its parent.
1334    fn in_line(&self) -> bool {
1335        match self.stack.last() {
1336            None => false,
1337            Some(Frame::Items { compact: true, .. }) => true,
1338            Some(Frame::Items { .. }) => match self.stack.iter().rev().nth(1) {
1339                Some(Frame::Element(element)) => element.lines == Lines::Inline,
1340                _ => unreachable!("sequences are in elements"),
1341            },
1342            Some(Frame::Element(element)) => element.lines == Lines::Inline,
1343        }
1344    }
1345
1346    /// Ends the start tag of the parent of the next element and starts a
1347    /// new line for it if the content of the parent is indented.
1348    fn before_child(&mut self) {
1349        self.close_start_tag();
1350        if self.config.indent == Indent::None {
1351            return;
1352        }
1353        let text_key = self.config.names.text_key;
1354        let mut frames = self.stack.iter_mut().rev();
1355        let element = match frames.next() {
1356            None => return,
1357            Some(Frame::Items {
1358                compact, started, ..
1359            }) => {
1360                // compact sequences are on the line of their first element
1361                if std::mem::replace(started, true) && *compact {
1362                    return;
1363                }
1364                match frames.next() {
1365                    Some(Frame::Element(element)) => element,
1366                    _ => unreachable!("sequences are in elements"),
1367                }
1368            }
1369            Some(Frame::Element(element)) => element,
1370        };
1371        if element.lines == Lines::Pending {
1372            // text that can still come is next to the child elements,
1373            // structs whose text comes after them are on a single line
1374            let text_ahead = !element.expanded
1375                && element
1376                    .fields
1377                    .is_some_and(|(names, cursor)| names[cursor..].contains(&text_key));
1378            element.lines = if text_ahead {
1379                Lines::Inline
1380            } else {
1381                Lines::Indented
1382            };
1383        }
1384        if element.lines == Lines::Indented {
1385            self.newline(self.depth);
1386        }
1387    }
1388
1389    /// Starts a new line indented for the depth.
1390    fn newline(&mut self, depth: usize) {
1391        self.out.push('\n');
1392        let (unit, count) = match self.config.indent {
1393            Indent::None => return,
1394            Indent::Spaces(width) => (' ', width * depth),
1395            Indent::Tab => ('\t', depth),
1396        };
1397        self.out.extend(std::iter::repeat_n(unit, count));
1398    }
1399
1400    /// Writes the start of a start tag and returns the name as written.
1401    ///
1402    /// The namespaces declared on an element (other than the root, see
1403    /// `bind_root`) are declared first, they are bound until the bindings
1404    /// are truncated to the ones before the element.
1405    fn start_tag(&mut self, name: &str, is_root: bool, state: &State) -> Result<String, Error> {
1406        let mut declarations = String::new();
1407        if !is_root && let Some(Declarations(namespaces)) = state.event::<Declarations>() {
1408            for (prefix, uri) in namespaces {
1409                check_prefix(prefix)?;
1410                if prefix == "xml" {
1411                    continue;
1412                }
1413                declare(prefix, uri, &mut declarations)?;
1414                self.local_bindings.push((prefix.clone(), uri.clone()));
1415            }
1416        }
1417        let name = self.qualify(name, false, &mut declarations)?;
1418        self.out.push('<');
1419        self.out.push_str(&name);
1420        if is_root {
1421            self.root_declarations = Some(self.base + self.out.len());
1422        }
1423        self.out.push_str(&declarations);
1424        Ok(name)
1425    }
1426
1427    /// Returns how a name is written, `{uri}local` names get the prefix
1428    /// of their namespace.
1429    ///
1430    /// Namespaces without prefix are declared on the root element as long
1431    /// as its declarations were not written, afterwards on the element
1432    /// that is being written (the declaration is added to `declarations`).
1433    fn qualify(
1434        &mut self,
1435        name: &str,
1436        is_attribute: bool,
1437        declarations: &mut String,
1438    ) -> Result<String, Error> {
1439        let Some((uri, local)) = split_name(name)? else {
1440            return Ok(name.to_string());
1441        };
1442        // the default namespace (the empty prefix) does not apply to
1443        // attributes
1444        let usable = |(prefix, bound): &&(String, String)| {
1445            bound == uri && !(is_attribute && prefix.is_empty())
1446        };
1447        // a binding is only in effect if its prefix is not bound again
1448        // closer to the element
1449        let scoped = &self.local_bindings;
1450        let bound = scoped
1451            .iter()
1452            .enumerate()
1453            .rev()
1454            .find(|(index, binding)| {
1455                usable(binding) && !scoped[index + 1..].iter().any(|(x, _)| *x == binding.0)
1456            })
1457            .map(|(_, binding)| binding)
1458            .or_else(|| {
1459                self.root_bindings
1460                    .iter()
1461                    .find(|binding| usable(binding) && !scoped.iter().any(|(x, _)| *x == binding.0))
1462            });
1463        let prefix = match bound {
1464            Some((prefix, _)) => prefix,
1465            None => {
1466                // prefixes are never shadowed
1467                let prefix = (0..)
1468                    .map(|n| format!("ns{n}"))
1469                    .find(|prefix| {
1470                        self.root_bindings
1471                            .iter()
1472                            .chain(&self.local_bindings)
1473                            .all(|(x, _)| x != prefix)
1474                    })
1475                    .unwrap();
1476                let bindings = if self.root_declared {
1477                    declare(&prefix, uri, declarations)?;
1478                    &mut self.local_bindings
1479                } else {
1480                    &mut self.root_bindings
1481                };
1482                bindings.push((prefix, uri.to_string()));
1483                &bindings.last().unwrap().0
1484            }
1485        };
1486        Ok(if prefix.is_empty() {
1487            local.to_string()
1488        } else {
1489            format!("{prefix}:{local}")
1490        })
1491    }
1492
1493    /// Writes the namespace declarations of the root element.
1494    fn declare_root(&mut self) -> Result<(), Error> {
1495        if self.root_declared {
1496            return Ok(());
1497        }
1498        self.root_declared = true;
1499        let Some(at) = self.root_declarations else {
1500            return Ok(());
1501        };
1502        let mut declarations = String::new();
1503        for (prefix, uri) in &self.root_bindings[1..] {
1504            declare(prefix, uri, &mut declarations)?;
1505        }
1506        self.insert(at, &declarations);
1507        Ok(())
1508    }
1509
1510    /// Returns where the output that is not final starts.
1511    fn final_until(&self) -> usize {
1512        for frame in &self.stack {
1513            if let Frame::Element(element) = frame
1514                && !matches!(element.attrs, Attrs::Done)
1515            {
1516                return element.attrs_at;
1517            }
1518        }
1519        self.base + self.out.len()
1520    }
1521
1522    /// Returns how much of the output that was not passed on is final.
1523    ///
1524    /// Once the start tag of the root element is final, its namespace
1525    /// declarations are written.  Namespaces that are found afterwards are
1526    /// declared on the elements that use them.
1527    fn final_len(&mut self) -> Result<usize, Error> {
1528        let mut until = self.final_until();
1529        // the declarations of the root element are final with it
1530        if !self.root_declared && self.root_declarations.is_some_and(|at| at < until) {
1531            self.declare_root()?;
1532            until = self.final_until();
1533        }
1534        Ok(until - self.base)
1535    }
1536
1537    /// Passes the output that is final on.
1538    fn pass_on(&mut self, out: &mut String) {
1539        let len = self.final_until() - self.base;
1540        out.push_str(&self.out[..len]);
1541        self.out.drain(..len);
1542        self.base += len;
1543    }
1544
1545    /// Completes the output once the document was written, the output
1546    /// that was not passed on is final afterwards.
1547    fn finish(&mut self) -> Result<(), Error> {
1548        if !self.stack.is_empty() || self.depth > 0 {
1549            return Err(Error::new(ErrorKind::InvalidState, "incomplete document"));
1550        }
1551        self.declare_root()
1552    }
1553
1554    /// Ends the start tag of the element that contains the next content.
1555    fn close_start_tag(&mut self) {
1556        let element = self.stack.iter_mut().rev().find_map(|frame| match frame {
1557            Frame::Element(element) => Some(element),
1558            Frame::Items { .. } => None,
1559        });
1560        if let Some(element) = element
1561            && !element.content
1562        {
1563            element.content = true;
1564            self.out.push('>');
1565        }
1566    }
1567
1568    fn close_element(&mut self) -> Result<(), Error> {
1569        if let Some(Frame::Element(element)) = self.stack.last_mut() {
1570            element.attrs = Attrs::Done;
1571        }
1572        self.settle();
1573        let Some(Frame::Element(element)) = self.stack.pop() else {
1574            unreachable!()
1575        };
1576        self.depth -= 1;
1577        if element.lines == Lines::Indented {
1578            self.newline(self.depth);
1579        }
1580        if element.content {
1581            write!(self.out, "</{}>", element.name).unwrap();
1582        } else {
1583            self.out.push_str("/>");
1584        }
1585        self.local_bindings.truncate(element.bindings);
1586        Ok(())
1587    }
1588
1589    /// Returns the text of an atom, `None` for null.
1590    fn text<'a>(&self, atom: &'a Atom<'_>) -> Result<Option<Cow<'a, str>>, Error> {
1591        Ok(Some(match *atom {
1592            Atom::Null => return Ok(None),
1593            // implicit values keep their text if it's the same value in
1594            // XML Schema, which is the case for all but `~`, `.inf`, ...
1595            Atom::Implicit(ref value) => {
1596                return Ok(self
1597                    .text(&value.value().to_atom())?
1598                    .map(|text| Cow::Owned(text.into_owned())));
1599            }
1600            Atom::Bool(value) => Cow::Borrowed(if value { "true" } else { "false" }),
1601            Atom::Str(ref value) | Atom::Lexical(ref value) => Cow::Borrowed(&**value),
1602            Atom::Char(value) => Cow::Owned(value.to_string()),
1603            Atom::U64(value) => Cow::Owned(value.to_string()),
1604            Atom::I64(value) => Cow::Owned(value.to_string()),
1605            Atom::F32(value) => Cow::Owned(float_text(value)),
1606            Atom::F64(value) => Cow::Owned(float_text(value)),
1607            Atom::Bytes(ref bytes) => {
1608                let format = bytes.fallback.copied().unwrap_or(self.bytes);
1609                Cow::Owned(
1610                    format
1611                        .encode(bytes)
1612                        .or_else(|| BytesFormat::BASE64.encode(bytes))
1613                        .unwrap_or_default(),
1614                )
1615            }
1616            Atom::Ext(ref ext) => {
1617                if let Some(number) = ext.downcast_value_ref::<Number>() {
1618                    Cow::Owned(number.as_str().to_string())
1619                } else if let Some(value) = ext.downcast_ref::<u128>() {
1620                    Cow::Owned(value.to_string())
1621                } else if let Some(value) = ext.downcast_ref::<i128>() {
1622                    Cow::Owned(value.to_string())
1623                } else {
1624                    match ext.fallback() {
1625                        Atom::Ext(_) => {
1626                            return Err(Error::new(
1627                                ErrorKind::UnsupportedType,
1628                                format!("XML does not support {}", ext.name()),
1629                            ));
1630                        }
1631                        fallback => match self.text(&fallback)? {
1632                            Some(text) => Cow::Owned(text.into_owned()),
1633                            None => return Ok(None),
1634                        },
1635                    }
1636                }
1637            }
1638            _ => {
1639                return Err(Error::new(
1640                    ErrorKind::UnsupportedType,
1641                    format!("XML does not support {}", atom.name()),
1642                ));
1643            }
1644        }))
1645    }
1646}
1647
1648/// Returns `true` if the event starts content that keeps whitespace.
1649fn keeps_whitespace(state: &State) -> bool {
1650    state
1651        .event::<KeepsWhitespace>()
1652        .is_some_and(|keeps| keeps.0)
1653}
1654
1655/// Returns the text of a float.
1656///
1657/// Finite floats have the shortest text that reads back as the same value
1658/// of their type, like in the other formats.  The others are written as in
1659/// XML Schema.
1660fn float_text<F: zmij::Float + Into<f64>>(value: F) -> String {
1661    let wide: f64 = value.into();
1662    if wide.is_nan() {
1663        "NaN".into()
1664    } else if wide.is_infinite() {
1665        if wide > 0.0 { "INF" } else { "-INF" }.into()
1666    } else {
1667        zmij::Buffer::new().format_finite(value).into()
1668    }
1669}
1670
1671/// Escapes text or the value of an attribute.
1672fn escape(text: &str, attribute: bool, out: &mut String) -> Result<(), Error> {
1673    for c in text.chars() {
1674        match c {
1675            '&' => out.push_str("&amp;"),
1676            '<' => out.push_str("&lt;"),
1677            '>' => out.push_str("&gt;"),
1678            '"' if attribute => out.push_str("&quot;"),
1679            // attribute values are normalized, whitespace is kept with
1680            // references
1681            '\t' if attribute => out.push_str("&#9;"),
1682            '\n' if attribute => out.push_str("&#10;"),
1683            '\r' => out.push_str("&#13;"),
1684            '\t' | '\n' => out.push(c),
1685            c if (c as u32) < 0x20 || c == '\u{fffe}' || c == '\u{ffff}' => {
1686                return Err(Error::new(
1687                    ErrorKind::UnsupportedType,
1688                    format!("the character {c:?} cannot be written in XML"),
1689                ));
1690            }
1691            c => out.push(c),
1692        }
1693    }
1694    Ok(())
1695}
1696
1697/// Returns the name of the attribute a key stands for.
1698///
1699/// The text key is checked before.
1700fn attribute_name<'a>(names: &Names, key: &'a str) -> Option<&'a str> {
1701    key.strip_prefix(names.attribute_prefix)
1702        .filter(|_| !names.attribute_prefix.is_empty())
1703}
1704
1705/// Writes the declaration of a namespace prefix.
1706fn declare(prefix: &str, uri: &str, out: &mut String) -> Result<(), Error> {
1707    out.push_str(" xmlns");
1708    if !prefix.is_empty() {
1709        out.push(':');
1710        out.push_str(prefix);
1711    }
1712    out.push_str("=\"");
1713    escape(uri, true, out)?;
1714    out.push('"');
1715    Ok(())
1716}
1717
1718/// Splits a `{uri}local` name, other names are `None`.
1719fn split_name(name: &str) -> Result<Option<(&str, &str)>, Error> {
1720    let Some(rest) = name.strip_prefix('{') else {
1721        return Ok(None);
1722    };
1723    match rest.split_once('}') {
1724        Some((uri, local)) if !uri.is_empty() => Ok(Some((uri, local))),
1725        _ => Err(Error::new(
1726            ErrorKind::UnsupportedType,
1727            format!("`{name}` is not a name in XML"),
1728        )),
1729    }
1730}
1731
1732/// Checks that a name is a name in XML or a `{uri}local` name whose local
1733/// name has no prefix.
1734fn check_element_name(name: &str) -> Result<(), Error> {
1735    match split_name(name)? {
1736        Some((_, local)) if local.contains(':') => Err(Error::new(
1737            ErrorKind::UnsupportedType,
1738            format!("`{name}` is not a name in XML"),
1739        )),
1740        Some((_, local)) => check_name(local),
1741        None => check_name(name),
1742    }
1743}
1744
1745/// Checks that a prefix of a namespace is a prefix in XML (the empty
1746/// prefix is the default namespace).
1747fn check_prefix(prefix: &str) -> Result<(), Error> {
1748    if prefix.is_empty() {
1749        return Ok(());
1750    }
1751    check_name(prefix)?;
1752    if prefix.contains(':') {
1753        return Err(Error::new(
1754            ErrorKind::UnsupportedType,
1755            format!("`{prefix}` is not a prefix in XML"),
1756        ));
1757    }
1758    Ok(())
1759}
1760
1761/// Checks that a name is a name in XML.
1762fn check_name(name: &str) -> Result<(), Error> {
1763    let mut chars = name.chars();
1764    let valid = match chars.next() {
1765        Some(c) if c.is_alphabetic() || c == '_' || c == ':' => {
1766            chars.all(|c| c.is_alphanumeric() || matches!(c, '_' | ':' | '-' | '.' | '\u{b7}'))
1767        }
1768        _ => false,
1769    };
1770    if valid {
1771        Ok(())
1772    } else {
1773        Err(Error::new(
1774            ErrorKind::UnsupportedType,
1775            format!("`{name}` is not a name in XML"),
1776        ))
1777    }
1778}
1779
1780#[cold]
1781fn unsupported_key() -> Error {
1782    Error::new(
1783        ErrorKind::UnsupportedType,
1784        "the keys of elements must be names",
1785    )
1786}
1787
1788#[cfg(test)]
1789mod tests {
1790    use std::collections::BTreeMap;
1791
1792    use deser::Serialize;
1793
1794    use super::*;
1795
1796    /// Serializes a value in pieces that are passed on as early as possible
1797    /// (the driver pauses between values).
1798    fn pieces<T: Serialize + ?Sized>(
1799        config: &SerializerConfig,
1800        value: &T,
1801    ) -> Result<Vec<String>, Error> {
1802        let mut pieces = Vec::new();
1803        let mut driver = SerializeDriver::new(&value);
1804        let mut progress = None;
1805        loop {
1806            let mut out = String::new();
1807            let done = config.serialize_part(&mut progress, &mut driver, &mut out, 1)?;
1808            pieces.push(out);
1809            if done {
1810                return Ok(pieces);
1811            }
1812        }
1813    }
1814
1815    #[derive(Serialize)]
1816    struct Feed {
1817        #[deser(rename = "@id")]
1818        id: u32,
1819        title: &'static str,
1820        entry: Vec<Entry>,
1821    }
1822
1823    #[derive(Serialize)]
1824    struct Entry {
1825        #[deser(rename = "$text")]
1826        text: &'static str,
1827        #[deser(rename = "@n")]
1828        n: u32,
1829        #[deser(skip_serializing_if = Option::is_none)]
1830        note: Option<&'static str>,
1831    }
1832
1833    fn feed() -> Feed {
1834        Feed {
1835            id: 1,
1836            title: "t",
1837            entry: vec![
1838                Entry {
1839                    text: "a",
1840                    n: 1,
1841                    note: None,
1842                },
1843                Entry {
1844                    text: "b",
1845                    n: 2,
1846                    note: Some("x"),
1847                },
1848            ],
1849        }
1850    }
1851
1852    #[test]
1853    fn test_structs_stream() {
1854        // output is final once no more attributes can come, late
1855        // attributes hold back the rest of the element until they come
1856        assert_eq!(
1857            pieces(&SerializerConfig::new(), &feed()).unwrap(),
1858            [
1859                "<Feed id=\"1\"",
1860                "><title>t</title>",
1861                "<entry",
1862                " n=\"1\">a",
1863                "</entry>",
1864                "<entry",
1865                " n=\"2\">b",
1866                "<note>x</note>",
1867                "</entry>",
1868                "</Feed>",
1869            ]
1870        );
1871    }
1872
1873    #[test]
1874    fn test_maps_are_buffered() {
1875        // the keys of maps are not known, their elements are final at the end
1876        let config = SerializerConfig::builder()
1877            .root("m")
1878            .declaration(true)
1879            .build();
1880        let map = BTreeMap::from([
1881            ("a", BTreeMap::from([("$text", "1"), ("@x", "2")])),
1882            ("b", BTreeMap::from([("$text", "3"), ("@y", "4")])),
1883        ]);
1884        assert_eq!(
1885            pieces(&config, &map).unwrap(),
1886            [
1887                "<?xml version=\"1.0\" encoding=\"UTF-8\"?><m",
1888                "><a x=\"2\">1</a><b y=\"4\">3</b></m>",
1889            ]
1890        );
1891
1892        let map = BTreeMap::from([("$text", "x"), ("@a", "1"), ("b", "2")]);
1893        assert_eq!(
1894            pieces(&config, &map).unwrap(),
1895            [
1896                "<?xml version=\"1.0\" encoding=\"UTF-8\"?><m",
1897                " a=\"1\">x<b>2</b></m>",
1898            ]
1899        );
1900    }
1901
1902    #[test]
1903    fn test_same_output() {
1904        let map = BTreeMap::from([("$text", "x"), ("@a", "1"), ("b", "2")]);
1905        let nested = BTreeMap::from([("a", BTreeMap::from([("@x", "1"), ("b", "2")]))]);
1906        let feed = feed();
1907        let values: [SerializeRef<'_>; 4] = [
1908            SerializeRef::new(&feed),
1909            SerializeRef::new(&map),
1910            SerializeRef::new(&nested),
1911            SerializeRef::new(&Some(42)),
1912        ];
1913        for config in [
1914            SerializerConfig::builder().root("r").build(),
1915            SerializerConfig::builder()
1916                .root("r")
1917                .declaration(true)
1918                .indent(Indent::Spaces(2))
1919                .build(),
1920        ] {
1921            for value in values {
1922                assert_eq!(
1923                    pieces(&config, &value).unwrap().concat(),
1924                    config.to_string(&value).unwrap()
1925                );
1926            }
1927        }
1928    }
1929
1930    #[test]
1931    fn test_indent_streams() {
1932        // indentation does not hold back output
1933        let config = SerializerConfig::builder()
1934            .indent(Indent::Spaces(2))
1935            .build();
1936        assert_eq!(
1937            pieces(&config, &feed()).unwrap(),
1938            [
1939                "<Feed id=\"1\"",
1940                ">\n  <title>t</title>",
1941                "\n  <entry",
1942                " n=\"1\">a",
1943                "</entry>",
1944                "\n  <entry",
1945                " n=\"2\">b",
1946                "<note>x</note>",
1947                "</entry>",
1948                "\n</Feed>",
1949            ]
1950        );
1951    }
1952
1953    #[test]
1954    fn test_namespaces_stream() {
1955        #[derive(Serialize)]
1956        #[deser(rename = "{urn:root}root")]
1957        struct Root {
1958            #[deser(rename = "{urn:a}a")]
1959            a: Vec<Child>,
1960        }
1961
1962        #[derive(Serialize)]
1963        struct Child {
1964            #[deser(rename = "@{urn:b}b")]
1965            b: u32,
1966            #[deser(rename = "{urn:a}c")]
1967            c: u32,
1968        }
1969
1970        let root = Root {
1971            a: vec![Child { b: 1, c: 2 }, Child { b: 3, c: 4 }],
1972        };
1973
1974        // written at once, all namespaces are declared on the root
1975        let config = SerializerConfig::new();
1976        assert_eq!(
1977            config.to_string(&root).unwrap(),
1978            "<ns0:root xmlns:ns0=\"urn:root\" xmlns:ns1=\"urn:a\" xmlns:ns2=\"urn:b\">\
1979             <ns1:a ns2:b=\"1\"><ns1:c>2</ns1:c></ns1:a>\
1980             <ns1:a ns2:b=\"3\"><ns1:c>4</ns1:c></ns1:a></ns0:root>"
1981        );
1982
1983        // streamed, the ones that are found after the start tag of the root
1984        // was written are declared where they are used
1985        assert_eq!(
1986            pieces(&config, &root).unwrap().concat(),
1987            "<ns0:root xmlns:ns0=\"urn:root\" xmlns:ns1=\"urn:a\">\
1988             <ns1:a xmlns:ns2=\"urn:b\" ns2:b=\"1\"><ns1:c>2</ns1:c></ns1:a>\
1989             <ns1:a xmlns:ns2=\"urn:b\" ns2:b=\"3\"><ns1:c>4</ns1:c></ns1:a>\
1990             </ns0:root>"
1991        );
1992
1993        // configured namespaces are always declared on the root
1994        let config = SerializerConfig::new().namespaces(&[("r", "urn:root"), ("a", "urn:a")]);
1995        assert_eq!(
1996            pieces(&config, &root).unwrap().concat(),
1997            "<r:root xmlns:r=\"urn:root\" xmlns:a=\"urn:a\">\
1998             <a:a xmlns:ns0=\"urn:b\" ns0:b=\"1\"><a:c>2</a:c></a:a>\
1999             <a:a xmlns:ns0=\"urn:b\" ns0:b=\"3\"><a:c>4</a:c></a:a></r:root>"
2000        );
2001    }
2002
2003    #[test]
2004    fn test_nested_declarations_stream() {
2005        const RESOLVE: crate::DeserializerConfig = crate::DeserializerConfig::builder()
2006            .resolve_namespaces(true)
2007            .build();
2008        let input = r#"<a:r xmlns:a="urn:a"><b xmlns:a="urn:b"><x>1</x></b><a:y>2</a:y></a:r>"#;
2009        let mut value: deser_value::Value = RESOLVE.from_str(input).unwrap();
2010        let config = SerializerConfig::new();
2011        assert_eq!(pieces(&config, &value).unwrap().concat(), input);
2012
2013        // a namespace whose prefix is bound again gets another one
2014        let b = value.as_map_mut().unwrap().get_mut("b").unwrap();
2015        b.as_map_mut().unwrap().insert("{urn:a}z", "3");
2016        let xml = config.to_string(&value).unwrap();
2017        assert_eq!(
2018            xml,
2019            "<a:r xmlns:a=\"urn:a\" xmlns:ns0=\"urn:a\"><b xmlns:a=\"urn:b\"><x>1</x>\
2020             <ns0:z>3</ns0:z></b><a:y>2</a:y></a:r>"
2021        );
2022        assert_eq!(pieces(&config, &value).unwrap().concat(), xml);
2023    }
2024
2025    #[test]
2026    fn test_wrong_fields() {
2027        // a value whose keys are not the fields it describes
2028        struct Wrong(BTreeMap<&'static str, &'static str>);
2029
2030        impl Serialize for Wrong {
2031            fn describe(_value: &Self, d: &mut dyn Describe) {
2032                d.structure("Wrong");
2033                d.fields(&["$text"]);
2034            }
2035
2036            fn serialize<'a>(
2037                value: &'a Self,
2038                state: &mut deser_core::State,
2039            ) -> Result<deser_core::ser::Emit<'a>, Error> {
2040                BTreeMap::<&str, &str>::serialize(&value.0, state)
2041            }
2042        }
2043
2044        let wrong = Wrong(BTreeMap::from([("$text", "x"), ("@a", "1")]));
2045        let config = SerializerConfig::new();
2046        // written at once, the attribute can still go into the start tag
2047        assert_eq!(
2048            config.to_string(&wrong).unwrap(),
2049            r#"<Wrong a="1">x</Wrong>"#
2050        );
2051        let err = pieces(&config, &wrong).unwrap_err();
2052        assert!(
2053            err.message()
2054                .starts_with("attribute `a` comes after the start tag")
2055        );
2056    }
2057}