Skip to main content

deser_xml/
ser.rs

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