quick_xml/se/
mod.rs

1//! Module to handle custom serde `Serializer`
2
3/// Implements writing primitives to the underlying writer.
4/// Implementor must provide `write_str(self, &str) -> Result<(), DeError>` method
5macro_rules! write_primitive {
6    ($method:ident ( $ty:ty )) => {
7        fn $method(mut self, value: $ty) -> Result<Self::Ok, Self::Error> {
8            self.write_str(&value.to_string())?;
9            Ok(self.writer)
10        }
11    };
12    () => {
13        fn serialize_bool(mut self, value: bool) -> Result<Self::Ok, Self::Error> {
14            self.write_str(if value { "true" } else { "false" })?;
15            Ok(self.writer)
16        }
17
18        write_primitive!(serialize_i8(i8));
19        write_primitive!(serialize_i16(i16));
20        write_primitive!(serialize_i32(i32));
21        write_primitive!(serialize_i64(i64));
22
23        write_primitive!(serialize_u8(u8));
24        write_primitive!(serialize_u16(u16));
25        write_primitive!(serialize_u32(u32));
26        write_primitive!(serialize_u64(u64));
27
28        serde_if_integer128! {
29            write_primitive!(serialize_i128(i128));
30            write_primitive!(serialize_u128(u128));
31        }
32
33        write_primitive!(serialize_f32(f32));
34        write_primitive!(serialize_f64(f64));
35
36        fn serialize_char(self, value: char) -> Result<Self::Ok, Self::Error> {
37            self.serialize_str(&value.to_string())
38        }
39
40        fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> {
41            //TODO: customization point - allow user to decide how to encode bytes
42            Err(DeError::Unsupported(
43                "`serialize_bytes` not supported yet".into(),
44            ))
45        }
46
47        fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
48            Ok(self.writer)
49        }
50
51        fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok, Self::Error> {
52            value.serialize(self)
53        }
54
55        fn serialize_unit_variant(
56            self,
57            _name: &'static str,
58            _variant_index: u32,
59            variant: &'static str,
60        ) -> Result<Self::Ok, Self::Error> {
61            self.serialize_str(variant)
62        }
63
64        fn serialize_newtype_struct<T: ?Sized + Serialize>(
65            self,
66            _name: &'static str,
67            value: &T,
68        ) -> Result<Self::Ok, Self::Error> {
69            value.serialize(self)
70        }
71    };
72}
73
74////////////////////////////////////////////////////////////////////////////////////////////////////
75
76mod content;
77mod element;
78pub(crate) mod key;
79pub(crate) mod simple_type;
80mod text;
81
82use self::content::ContentSerializer;
83use self::element::{ElementSerializer, Map, Struct, Tuple};
84use crate::de::TEXT_KEY;
85use crate::errors::serialize::DeError;
86use crate::writer::Indentation;
87use serde::ser::{self, Serialize};
88use serde::serde_if_integer128;
89use std::fmt::Write;
90use std::str::from_utf8;
91
92/// Serialize struct into a `Write`r.
93///
94/// # Examples
95///
96/// ```
97/// # use quick_xml::se::to_writer;
98/// # use serde::Serialize;
99/// # use pretty_assertions::assert_eq;
100/// #[derive(Serialize)]
101/// struct Root<'a> {
102///     #[serde(rename = "@attribute")]
103///     attribute: &'a str,
104///     element: &'a str,
105///     #[serde(rename = "$text")]
106///     text: &'a str,
107/// }
108///
109/// let data = Root {
110///     attribute: "attribute content",
111///     element: "element content",
112///     text: "text content",
113/// };
114///
115/// let mut buffer = String::new();
116/// to_writer(&mut buffer, &data).unwrap();
117/// assert_eq!(
118///     buffer,
119///     // The root tag name is automatically deduced from the struct name
120///     // This will not work for other types or struct with #[serde(flatten)] fields
121///     "<Root attribute=\"attribute content\">\
122///         <element>element content</element>\
123///         text content\
124///     </Root>"
125/// );
126/// ```
127pub fn to_writer<W, T>(mut writer: W, value: &T) -> Result<(), DeError>
128where
129    W: Write,
130    T: ?Sized + Serialize,
131{
132    value.serialize(Serializer::new(&mut writer))
133}
134
135/// Serialize struct into a `String`.
136///
137/// # Examples
138///
139/// ```
140/// # use quick_xml::se::to_string;
141/// # use serde::Serialize;
142/// # use pretty_assertions::assert_eq;
143/// #[derive(Serialize)]
144/// struct Root<'a> {
145///     #[serde(rename = "@attribute")]
146///     attribute: &'a str,
147///     element: &'a str,
148///     #[serde(rename = "$text")]
149///     text: &'a str,
150/// }
151///
152/// let data = Root {
153///     attribute: "attribute content",
154///     element: "element content",
155///     text: "text content",
156/// };
157///
158/// assert_eq!(
159///     to_string(&data).unwrap(),
160///     // The root tag name is automatically deduced from the struct name
161///     // This will not work for other types or struct with #[serde(flatten)] fields
162///     "<Root attribute=\"attribute content\">\
163///         <element>element content</element>\
164///         text content\
165///     </Root>"
166/// );
167/// ```
168pub fn to_string<T>(value: &T) -> Result<String, DeError>
169where
170    T: ?Sized + Serialize,
171{
172    let mut buffer = String::new();
173    to_writer(&mut buffer, value)?;
174    Ok(buffer)
175}
176
177/// Serialize struct into a `Write`r using specified root tag name.
178/// `root_tag` should be valid [XML name], otherwise error is returned.
179///
180/// # Examples
181///
182/// ```
183/// # use quick_xml::se::to_writer_with_root;
184/// # use serde::Serialize;
185/// # use pretty_assertions::assert_eq;
186/// #[derive(Serialize)]
187/// struct Root<'a> {
188///     #[serde(rename = "@attribute")]
189///     attribute: &'a str,
190///     element: &'a str,
191///     #[serde(rename = "$text")]
192///     text: &'a str,
193/// }
194///
195/// let data = Root {
196///     attribute: "attribute content",
197///     element: "element content",
198///     text: "text content",
199/// };
200///
201/// let mut buffer = String::new();
202/// to_writer_with_root(&mut buffer, "top-level", &data).unwrap();
203/// assert_eq!(
204///     buffer,
205///     "<top-level attribute=\"attribute content\">\
206///         <element>element content</element>\
207///         text content\
208///     </top-level>"
209/// );
210/// ```
211///
212/// [XML name]: https://www.w3.org/TR/xml11/#NT-Name
213pub fn to_writer_with_root<W, T>(mut writer: W, root_tag: &str, value: &T) -> Result<(), DeError>
214where
215    W: Write,
216    T: ?Sized + Serialize,
217{
218    value.serialize(Serializer::with_root(&mut writer, Some(root_tag))?)
219}
220
221/// Serialize struct into a `String` using specified root tag name.
222/// `root_tag` should be valid [XML name], otherwise error is returned.
223///
224/// # Examples
225///
226/// ```
227/// # use quick_xml::se::to_string_with_root;
228/// # use serde::Serialize;
229/// # use pretty_assertions::assert_eq;
230/// #[derive(Serialize)]
231/// struct Root<'a> {
232///     #[serde(rename = "@attribute")]
233///     attribute: &'a str,
234///     element: &'a str,
235///     #[serde(rename = "$text")]
236///     text: &'a str,
237/// }
238///
239/// let data = Root {
240///     attribute: "attribute content",
241///     element: "element content",
242///     text: "text content",
243/// };
244///
245/// assert_eq!(
246///     to_string_with_root("top-level", &data).unwrap(),
247///     "<top-level attribute=\"attribute content\">\
248///         <element>element content</element>\
249///         text content\
250///     </top-level>"
251/// );
252/// ```
253///
254/// [XML name]: https://www.w3.org/TR/xml11/#NT-Name
255pub fn to_string_with_root<T>(root_tag: &str, value: &T) -> Result<String, DeError>
256where
257    T: ?Sized + Serialize,
258{
259    let mut buffer = String::new();
260    to_writer_with_root(&mut buffer, root_tag, value)?;
261    Ok(buffer)
262}
263
264////////////////////////////////////////////////////////////////////////////////////////////////////
265
266/// Defines which characters would be escaped in [`Text`] events and attribute
267/// values.
268///
269/// [`Text`]: crate::events::Event::Text
270#[derive(Debug, Clone, Copy, PartialEq, Eq)]
271pub enum QuoteLevel {
272    /// Performs escaping, escape all characters that could have special meaning
273    /// in the XML. This mode is compatible with SGML specification.
274    ///
275    /// Characters that will be replaced:
276    ///
277    /// Original | Replacement
278    /// ---------|------------
279    /// `<`      | `&lt;`
280    /// `>`      | `&gt;`
281    /// `&`      | `&amp;`
282    /// `"`      | `&quot;`
283    /// `'`      | `&apos;`
284    Full,
285    /// Performs escaping that is compatible with SGML specification.
286    ///
287    /// This level adds escaping of `>` to the `Minimal` level, which is [required]
288    /// for compatibility with SGML.
289    ///
290    /// Characters that will be replaced:
291    ///
292    /// Original | Replacement
293    /// ---------|------------
294    /// `<`      | `&lt;`
295    /// `>`      | `&gt;`
296    /// `&`      | `&amp;`
297    ///
298    /// [required]: https://www.w3.org/TR/xml11/#syntax
299    Partial,
300    /// Performs the minimal possible escaping, escape only strictly necessary
301    /// characters.
302    ///
303    /// Characters that will be replaced:
304    ///
305    /// Original | Replacement
306    /// ---------|------------
307    /// `<`      | `&lt;`
308    /// `&`      | `&amp;`
309    Minimal,
310}
311
312////////////////////////////////////////////////////////////////////////////////////////////////////
313
314/// Implements serialization method by forwarding it to the serializer created by
315/// the helper method [`Serializer::ser`].
316macro_rules! forward {
317    ($name:ident($ty:ty)) => {
318        fn $name(self, value: $ty) -> Result<Self::Ok, Self::Error> {
319            self.ser(&concat!("`", stringify!($ty), "`"))?.$name(value)
320        }
321    };
322}
323
324////////////////////////////////////////////////////////////////////////////////////////////////////
325
326/// Almost all characters can form a name. Citation from <https://www.w3.org/TR/xml11/#sec-xml11>:
327///
328/// > The overall philosophy of names has changed since XML 1.0. Whereas XML 1.0
329/// > provided a rigid definition of names, wherein everything that was not permitted
330/// > was forbidden, XML 1.1 names are designed so that everything that is not
331/// > forbidden (for a specific reason) is permitted. Since Unicode will continue
332/// > to grow past version 4.0, further changes to XML can be avoided by allowing
333/// > almost any character, including those not yet assigned, in names.
334///
335/// <https://www.w3.org/TR/xml11/#NT-NameStartChar>
336const fn is_xml11_name_start_char(ch: char) -> bool {
337    match ch {
338        ':'
339        | 'A'..='Z'
340        | '_'
341        | 'a'..='z'
342        | '\u{00C0}'..='\u{00D6}'
343        | '\u{00D8}'..='\u{00F6}'
344        | '\u{00F8}'..='\u{02FF}'
345        | '\u{0370}'..='\u{037D}'
346        | '\u{037F}'..='\u{1FFF}'
347        | '\u{200C}'..='\u{200D}'
348        | '\u{2070}'..='\u{218F}'
349        | '\u{2C00}'..='\u{2FEF}'
350        | '\u{3001}'..='\u{D7FF}'
351        | '\u{F900}'..='\u{FDCF}'
352        | '\u{FDF0}'..='\u{FFFD}'
353        | '\u{10000}'..='\u{EFFFF}' => true,
354        _ => false,
355    }
356}
357/// <https://www.w3.org/TR/xml11/#NT-NameChar>
358const fn is_xml11_name_char(ch: char) -> bool {
359    match ch {
360        '-' | '.' | '0'..='9' | '\u{00B7}' | '\u{0300}'..='\u{036F}' | '\u{203F}'..='\u{2040}' => {
361            true
362        }
363        _ => is_xml11_name_start_char(ch),
364    }
365}
366
367/// Helper struct to self-defense from errors
368#[derive(Clone, Copy, Debug, PartialEq)]
369pub(self) struct XmlName<'n>(&'n str);
370
371impl<'n> XmlName<'n> {
372    /// Checks correctness of the XML name according to [XML 1.1 specification]
373    ///
374    /// [XML 1.1 specification]: https://www.w3.org/TR/xml11/#NT-Name
375    pub fn try_from(name: &'n str) -> Result<XmlName<'n>, DeError> {
376        //TODO: Customization point: allow user to decide if he want to reject or encode the name
377        match name.chars().next() {
378            Some(ch) if !is_xml11_name_start_char(ch) => Err(DeError::Unsupported(
379                format!("character `{ch}` is not allowed at the start of an XML name `{name}`")
380                    .into(),
381            )),
382            _ => match name.matches(|ch| !is_xml11_name_char(ch)).next() {
383                Some(s) => Err(DeError::Unsupported(
384                    format!("character `{s}` is not allowed in an XML name `{name}`").into(),
385                )),
386                None => Ok(XmlName(name)),
387            },
388        }
389    }
390}
391
392////////////////////////////////////////////////////////////////////////////////////////////////////
393
394pub(crate) enum Indent<'i> {
395    /// No indent should be written before the element
396    None,
397    /// The specified indent should be written. The type owns the buffer with indent
398    Owned(Indentation),
399    /// The specified indent should be written. The type borrows buffer with indent
400    /// from its owner
401    Borrow(&'i mut Indentation),
402}
403
404impl<'i> Indent<'i> {
405    pub fn borrow(&mut self) -> Indent {
406        match self {
407            Self::None => Indent::None,
408            Self::Owned(ref mut i) => Indent::Borrow(i),
409            Self::Borrow(i) => Indent::Borrow(i),
410        }
411    }
412
413    pub fn increase(&mut self) {
414        match self {
415            Self::None => {}
416            Self::Owned(i) => i.grow(),
417            Self::Borrow(i) => i.grow(),
418        }
419    }
420
421    pub fn decrease(&mut self) {
422        match self {
423            Self::None => {}
424            Self::Owned(i) => i.shrink(),
425            Self::Borrow(i) => i.shrink(),
426        }
427    }
428
429    pub fn write_indent<W: std::fmt::Write>(&mut self, mut writer: W) -> Result<(), DeError> {
430        match self {
431            Self::None => {}
432            Self::Owned(i) => {
433                writer.write_char('\n')?;
434                writer.write_str(from_utf8(i.current())?)?;
435            }
436            Self::Borrow(i) => {
437                writer.write_char('\n')?;
438                writer.write_str(from_utf8(i.current())?)?;
439            }
440        }
441        Ok(())
442    }
443}
444
445////////////////////////////////////////////////////////////////////////////////////////////////////
446
447/// A Serializer
448pub struct Serializer<'w, 'r, W: Write> {
449    ser: ContentSerializer<'w, 'r, W>,
450    /// Name of the root tag. If not specified, deduced from the structure name
451    root_tag: Option<XmlName<'r>>,
452}
453
454impl<'w, 'r, W: Write> Serializer<'w, 'r, W> {
455    /// Creates a new `Serializer` that uses struct name as a root tag name.
456    ///
457    /// Note, that attempt to serialize a non-struct (including unit structs
458    /// and newtype structs) will end up to an error. Use `with_root` to create
459    /// serializer with explicitly defined root element name
460    pub fn new(writer: &'w mut W) -> Self {
461        Self {
462            ser: ContentSerializer {
463                writer,
464                level: QuoteLevel::Full,
465                indent: Indent::None,
466                write_indent: false,
467                expand_empty_elements: false,
468            },
469            root_tag: None,
470        }
471    }
472
473    /// Creates a new `Serializer` that uses specified root tag name. `name` should
474    /// be valid [XML name], otherwise error is returned.
475    ///
476    /// # Examples
477    ///
478    /// When serializing a primitive type, only its representation will be written:
479    ///
480    /// ```
481    /// # use pretty_assertions::assert_eq;
482    /// # use serde::Serialize;
483    /// # use quick_xml::se::Serializer;
484    ///
485    /// let mut buffer = String::new();
486    /// let ser = Serializer::with_root(&mut buffer, Some("root")).unwrap();
487    ///
488    /// "node".serialize(ser).unwrap();
489    /// assert_eq!(buffer, "<root>node</root>");
490    /// ```
491    ///
492    /// When serializing a struct, newtype struct, unit struct or tuple `root_tag`
493    /// is used as tag name of root(s) element(s):
494    ///
495    /// ```
496    /// # use pretty_assertions::assert_eq;
497    /// # use serde::Serialize;
498    /// # use quick_xml::se::Serializer;
499    ///
500    /// #[derive(Debug, PartialEq, Serialize)]
501    /// struct Struct {
502    ///     question: String,
503    ///     answer: u32,
504    /// }
505    ///
506    /// let mut buffer = String::new();
507    /// let ser = Serializer::with_root(&mut buffer, Some("root")).unwrap();
508    ///
509    /// let data = Struct {
510    ///     question: "The Ultimate Question of Life, the Universe, and Everything".into(),
511    ///     answer: 42,
512    /// };
513    ///
514    /// data.serialize(ser).unwrap();
515    /// assert_eq!(
516    ///     buffer,
517    ///     "<root>\
518    ///         <question>The Ultimate Question of Life, the Universe, and Everything</question>\
519    ///         <answer>42</answer>\
520    ///      </root>"
521    /// );
522    /// ```
523    ///
524    /// [XML name]: https://www.w3.org/TR/xml11/#NT-Name
525    pub fn with_root(writer: &'w mut W, root_tag: Option<&'r str>) -> Result<Self, DeError> {
526        Ok(Self {
527            ser: ContentSerializer {
528                writer,
529                level: QuoteLevel::Full,
530                indent: Indent::None,
531                write_indent: false,
532                expand_empty_elements: false,
533            },
534            root_tag: root_tag.map(|tag| XmlName::try_from(tag)).transpose()?,
535        })
536    }
537
538    /// Enable or disable expansion of empty elements. Defaults to `false`.
539    ///
540    /// # Examples
541    ///
542    /// ```
543    /// # use pretty_assertions::assert_eq;
544    /// # use serde::Serialize;
545    /// # use quick_xml::se::Serializer;
546    ///
547    /// #[derive(Debug, PartialEq, Serialize)]
548    /// struct Struct {
549    ///     question: Option<String>,
550    /// }
551    ///
552    /// let mut buffer = String::new();
553    /// let mut ser = Serializer::new(&mut buffer);
554    /// ser.expand_empty_elements(true);
555    ///
556    /// let data = Struct {
557    ///   question: None,
558    /// };
559    ///
560    /// data.serialize(ser).unwrap();
561    /// assert_eq!(
562    ///     buffer,
563    ///     "<Struct><question></question></Struct>"
564    /// );
565    /// ```
566    pub fn expand_empty_elements(&mut self, expand: bool) -> &mut Self {
567        self.ser.expand_empty_elements = expand;
568        self
569    }
570
571    /// Configure indent for a serializer
572    pub fn indent(&mut self, indent_char: char, indent_size: usize) -> &mut Self {
573        self.ser.indent = Indent::Owned(Indentation::new(indent_char as u8, indent_size));
574        self
575    }
576
577    /// Set the indent object for a serializer
578    pub(crate) fn set_indent(&mut self, indent: Indent<'r>) -> &mut Self {
579        self.ser.indent = indent;
580        self
581    }
582
583    /// Creates actual serializer or returns an error if root tag is not defined.
584    /// In that case `err` contains the name of type that cannot be serialized.
585    fn ser(self, err: &str) -> Result<ElementSerializer<'w, 'r, W>, DeError> {
586        if let Some(key) = self.root_tag {
587            Ok(ElementSerializer { ser: self.ser, key })
588        } else {
589            Err(DeError::Unsupported(
590                format!("cannot serialize {} without defined root tag", err).into(),
591            ))
592        }
593    }
594
595    /// Creates actual serializer using root tag or a specified `key` if root tag
596    /// is not defined. Returns an error if root tag is not defined and a `key`
597    /// does not conform [XML rules](XmlName::try_from) for names.
598    fn ser_name(self, key: &'static str) -> Result<ElementSerializer<'w, 'r, W>, DeError> {
599        Ok(ElementSerializer {
600            ser: self.ser,
601            key: match self.root_tag {
602                Some(key) => key,
603                None => XmlName::try_from(key)?,
604            },
605        })
606    }
607}
608
609impl<'w, 'r, W: Write> ser::Serializer for Serializer<'w, 'r, W> {
610    type Ok = ();
611    type Error = DeError;
612
613    type SerializeSeq = ElementSerializer<'w, 'r, W>;
614    type SerializeTuple = ElementSerializer<'w, 'r, W>;
615    type SerializeTupleStruct = ElementSerializer<'w, 'r, W>;
616    type SerializeTupleVariant = Tuple<'w, 'r, W>;
617    type SerializeMap = Map<'w, 'r, W>;
618    type SerializeStruct = Struct<'w, 'r, W>;
619    type SerializeStructVariant = Struct<'w, 'r, W>;
620
621    forward!(serialize_bool(bool));
622
623    forward!(serialize_i8(i8));
624    forward!(serialize_i16(i16));
625    forward!(serialize_i32(i32));
626    forward!(serialize_i64(i64));
627
628    forward!(serialize_u8(u8));
629    forward!(serialize_u16(u16));
630    forward!(serialize_u32(u32));
631    forward!(serialize_u64(u64));
632
633    serde_if_integer128! {
634        forward!(serialize_i128(i128));
635        forward!(serialize_u128(u128));
636    }
637
638    forward!(serialize_f32(f32));
639    forward!(serialize_f64(f64));
640
641    forward!(serialize_char(char));
642    forward!(serialize_str(&str));
643    forward!(serialize_bytes(&[u8]));
644
645    fn serialize_none(self) -> Result<Self::Ok, DeError> {
646        Ok(())
647    }
648
649    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok, DeError> {
650        value.serialize(self)
651    }
652
653    fn serialize_unit(self) -> Result<Self::Ok, DeError> {
654        self.ser("`()`")?.serialize_unit()
655    }
656
657    fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, DeError> {
658        self.ser_name(name)?.serialize_unit_struct(name)
659    }
660
661    fn serialize_unit_variant(
662        self,
663        name: &'static str,
664        _variant_index: u32,
665        variant: &'static str,
666    ) -> Result<Self::Ok, DeError> {
667        if variant == TEXT_KEY {
668            // We should write some text but we don't known what text to write
669            Err(DeError::Unsupported(
670                format!(
671                    "cannot serialize enum unit variant `{}::$text` as text content value",
672                    name
673                )
674                .into(),
675            ))
676        } else {
677            let name = XmlName::try_from(variant)?;
678            self.ser.write_empty(name)
679        }
680    }
681
682    fn serialize_newtype_struct<T: ?Sized + Serialize>(
683        self,
684        name: &'static str,
685        value: &T,
686    ) -> Result<Self::Ok, DeError> {
687        self.ser_name(name)?.serialize_newtype_struct(name, value)
688    }
689
690    fn serialize_newtype_variant<T: ?Sized + Serialize>(
691        self,
692        _name: &'static str,
693        _variant_index: u32,
694        variant: &'static str,
695        value: &T,
696    ) -> Result<Self::Ok, DeError> {
697        if variant == TEXT_KEY {
698            value.serialize(self.ser.into_simple_type_serializer())?;
699            Ok(())
700        } else {
701            let ser = ElementSerializer {
702                ser: self.ser,
703                key: XmlName::try_from(variant)?,
704            };
705            value.serialize(ser)
706        }
707    }
708
709    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, DeError> {
710        self.ser("sequence")?.serialize_seq(len)
711    }
712
713    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, DeError> {
714        self.ser("unnamed tuple")?.serialize_tuple(len)
715    }
716
717    fn serialize_tuple_struct(
718        self,
719        name: &'static str,
720        len: usize,
721    ) -> Result<Self::SerializeTupleStruct, DeError> {
722        self.ser_name(name)?.serialize_tuple_struct(name, len)
723    }
724
725    fn serialize_tuple_variant(
726        self,
727        name: &'static str,
728        _variant_index: u32,
729        variant: &'static str,
730        len: usize,
731    ) -> Result<Self::SerializeTupleVariant, DeError> {
732        if variant == TEXT_KEY {
733            self.ser
734                .into_simple_type_serializer()
735                .serialize_tuple_struct(name, len)
736                .map(Tuple::Text)
737        } else {
738            let ser = ElementSerializer {
739                ser: self.ser,
740                key: XmlName::try_from(variant)?,
741            };
742            ser.serialize_tuple_struct(name, len).map(Tuple::Element)
743        }
744    }
745
746    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, DeError> {
747        self.ser("map")?.serialize_map(len)
748    }
749
750    fn serialize_struct(
751        self,
752        name: &'static str,
753        len: usize,
754    ) -> Result<Self::SerializeStruct, DeError> {
755        self.ser_name(name)?.serialize_struct(name, len)
756    }
757
758    fn serialize_struct_variant(
759        self,
760        name: &'static str,
761        _variant_index: u32,
762        variant: &'static str,
763        len: usize,
764    ) -> Result<Self::SerializeStructVariant, DeError> {
765        if variant == TEXT_KEY {
766            Err(DeError::Unsupported(
767                format!(
768                    "cannot serialize enum struct variant `{}::$text` as text content value",
769                    name
770                )
771                .into(),
772            ))
773        } else {
774            let ser = ElementSerializer {
775                ser: self.ser,
776                key: XmlName::try_from(variant)?,
777            };
778            ser.serialize_struct(name, len)
779        }
780    }
781}