xmlity_quick_xml/
ser.rs

1use core::str;
2use std::borrow::Cow;
3use std::collections::BTreeMap;
4use std::io::Write;
5use std::ops::DerefMut;
6
7use quick_xml::events::{BytesCData, BytesDecl, BytesEnd, BytesPI, BytesStart, BytesText, Event};
8use quick_xml::writer::Writer as QuickXmlWriter;
9
10use xmlity::NoopDeSerializer;
11use xmlity::{
12    ser::{self, Error as _, IncludePrefix, Unexpected},
13    ExpandedName, LocalName, Prefix, QName, Serialize, XmlNamespace,
14};
15
16use crate::{OwnedQuickName, XmlnsDeclaration};
17
18/// Errors that can occur when using this crate.
19#[derive(Debug, thiserror::Error)]
20pub enum Error {
21    /// Error from the `quick-xml` crate.
22    #[error("Quick XML error: {0}")]
23    QuickXml(#[from] quick_xml::Error),
24    /// Error from the `quick-xml` crate when handling attributes.
25    #[error("Attribute error: {0}")]
26    AttrError(#[from] quick_xml::events::attributes::AttrError),
27    /// IO errors.
28    #[error("IO error: {0}")]
29    Io(#[from] std::io::Error),
30    /// Custom errors from [`Serialize`] implementations.
31    #[error("Custom: {0}")]
32    Custom(String),
33    /// Invalid UTF-8 when serializing.
34    #[error("Invalid UTF-8: {0}")]
35    InvalidUtf8(#[from] std::string::FromUtf8Error),
36}
37
38impl xmlity::ser::Error for Error {
39    fn unexpected_serialize(unexpected: ser::Unexpected) -> Self {
40        Error::Custom(format!("Unexpected serialize: {unexpected:?}"))
41    }
42
43    fn custom<T: ToString>(msg: T) -> Self {
44        Error::Custom(msg.to_string())
45    }
46}
47
48fn serializer_to_string<T>(serializer: QuickXmlWriter<Vec<u8>>, value: &T) -> Result<String, Error>
49where
50    T: Serialize,
51{
52    let mut serializer = Serializer::from(serializer);
53    value.serialize(&mut serializer)?;
54    let bytes = serializer.into_inner();
55
56    String::from_utf8(bytes).map_err(Error::InvalidUtf8)
57}
58
59/// Serialize a value into a string.
60pub fn to_string<T>(value: &T) -> Result<String, Error>
61where
62    T: Serialize,
63{
64    serializer_to_string(QuickXmlWriter::new(Vec::new()), value)
65}
66
67/// Serialize a value into a string with pretty printing.
68pub fn to_string_pretty<T>(value: &T, indentation: usize) -> Result<String, Error>
69where
70    T: Serialize,
71{
72    serializer_to_string(
73        QuickXmlWriter::new_with_indent(Vec::new(), b' ', indentation),
74        value,
75    )
76}
77
78struct NamespaceScope<'a> {
79    pub defined_namespaces: BTreeMap<Prefix<'a>, XmlNamespace<'a>>,
80}
81
82impl<'a> NamespaceScope<'a> {
83    pub fn new() -> Self {
84        Self {
85            defined_namespaces: BTreeMap::new(),
86        }
87    }
88
89    const XML_PREFIX: Prefix<'static> = Prefix::new_dangerous("xml");
90    const XML_NAMESPACE: XmlNamespace<'static> =
91        XmlNamespace::new_dangerous("http://www.w3.org/XML/1998/namespace");
92
93    pub fn top_scope() -> Self {
94        let mut scope = Self::new();
95        scope
96            .defined_namespaces
97            .insert(Self::XML_PREFIX, Self::XML_NAMESPACE);
98        scope
99    }
100
101    pub fn get_namespace<'b>(&'b self, prefix: &'b Prefix<'b>) -> Option<&'b XmlNamespace<'a>> {
102        self.defined_namespaces.get(prefix)
103    }
104}
105
106struct NamespaceScopeContainer<'a> {
107    scopes: Vec<NamespaceScope<'a>>,
108    prefix_generator: PrefixGenerator,
109}
110
111struct PrefixGenerator {
112    count: usize,
113}
114
115impl PrefixGenerator {
116    pub fn index_to_name(index: usize) -> Prefix<'static> {
117        // 0 = a0
118        // 1 = a1
119        // 26 = b0
120        // 27 = b1
121        // 52 = c0
122        // 53 = c1
123        // ...
124
125        let letter = (index / 26) as u8 + b'a';
126        let number = (index % 26) as u8 + b'0';
127        let mut name = String::with_capacity(2);
128        name.push(letter as char);
129        name.push(number as char);
130        Prefix::new(name).expect("Invalid prefix generated")
131    }
132
133    pub fn new() -> Self {
134        Self { count: 0 }
135    }
136
137    pub fn new_prefix(&mut self) -> Prefix<'static> {
138        let name = Self::index_to_name(self.count);
139        self.count += 1;
140        name
141    }
142}
143
144impl<'a> NamespaceScopeContainer<'a> {
145    pub fn new() -> Self {
146        Self {
147            scopes: vec![NamespaceScope::top_scope()],
148            prefix_generator: PrefixGenerator::new(),
149        }
150    }
151
152    pub fn push_scope(&mut self) {
153        self.scopes.push(NamespaceScope::new())
154    }
155
156    pub fn pop_scope(&mut self) -> Option<NamespaceScope> {
157        self.scopes.pop()
158    }
159
160    pub fn get_namespace<'b>(&'b self, prefix: &'b Prefix<'b>) -> Option<&'b XmlNamespace<'a>> {
161        self.scopes
162            .iter()
163            .rev()
164            .find_map(|a| a.get_namespace(prefix))
165    }
166
167    /// Find matching prefix
168    pub fn find_matching_namespace<'b>(
169        &'b self,
170        namespace: &'_ XmlNamespace<'_>,
171    ) -> Option<&'b Prefix<'a>> {
172        self.scopes.iter().rev().find_map(|a| {
173            a.defined_namespaces
174                .iter()
175                .find(|(_, found_namespace)| namespace == *found_namespace)
176                .map(|(prefix, _)| prefix)
177        })
178    }
179
180    /// This function takes in a namespace and tries to resolve it in different ways depending on the options provided. Unless `always_declare` is true, it will try to use an existing declaration. Otherwise, or if the namespace has not yet been declared, it will provide a declaration.
181    pub fn resolve_namespace<'b>(
182        &'b mut self,
183        namespace: &'_ XmlNamespace<'b>,
184        preferred_prefix: Option<&'b Prefix<'b>>,
185        always_declare: IncludePrefix,
186    ) -> (Prefix<'a>, Option<XmlnsDeclaration<'a>>) {
187        if always_declare != IncludePrefix::Always {
188            let existing_prefix = self.find_matching_namespace(namespace);
189
190            if let Some(existing_prefix) = existing_prefix {
191                if (always_declare == IncludePrefix::WhenNecessaryForPreferredPrefix
192                    && preferred_prefix
193                        .is_none_or(|preferred_prefix| preferred_prefix == existing_prefix))
194                    || always_declare == IncludePrefix::Never
195                {
196                    return (existing_prefix.clone(), None);
197                }
198            }
199        }
200
201        // If the namespace is not declared, use the specifically requested preferred prefix...
202        // ...if it is not already used and not the same as the existing prefix.
203        let prefix = preferred_prefix
204            .filter(|p| self.get_namespace(p).is_none_or(|n| n == namespace))
205            // If the preferred prefix is not available, use the preferred namespace prefix from the serializer...
206            .or_else(|| {
207                preferred_prefix
208                    // ...if it is not already used and not the same as the existing prefix.
209                    .filter(|p| self.get_namespace(p).is_none_or(|n| n == namespace))
210            })
211            .cloned()
212            // If the preferred namespace prefix is not available, use a random prefix.
213            .unwrap_or_else(|| self.prefix_generator.new_prefix())
214            .into_owned();
215
216        let scope = self
217            .scopes
218            .last_mut()
219            .expect("There should be at least one scope");
220
221        scope
222            .defined_namespaces
223            .insert(prefix.clone(), namespace.clone().into_owned());
224
225        let (prefix, namespace) = scope
226            .defined_namespaces
227            .get_key_value(&prefix)
228            .expect("The namespace should be defined as it was just added");
229
230        let xmlns = XmlnsDeclaration::new(prefix.clone(), namespace.clone());
231
232        (prefix.clone(), Some(xmlns))
233    }
234
235    pub fn resolve_name<'c>(
236        &'c mut self,
237        local_name: LocalName<'c>,
238        namespace: &Option<XmlNamespace<'c>>,
239        preferred_prefix: Option<&'c Prefix<'c>>,
240        always_declare: IncludePrefix,
241    ) -> (QName<'a>, Option<XmlnsDeclaration<'a>>) {
242        let (prefix, declaration) = namespace
243            .as_ref()
244            .map(|namespace| self.resolve_namespace(namespace, preferred_prefix, always_declare))
245            .unzip();
246
247        let declaration = declaration.flatten();
248
249        let name = QName::new(prefix, local_name.into_owned());
250        (name, declaration)
251    }
252}
253
254/// The [`xmlity::Deserializer`] for the `quick-xml` crate.
255pub struct Serializer<W: Write> {
256    writer: QuickXmlWriter<W>,
257    preferred_namespace_prefixes: BTreeMap<XmlNamespace<'static>, Prefix<'static>>,
258    namespace_scopes: NamespaceScopeContainer<'static>,
259    buffered_bytes_start: BytesStart<'static>,
260    buffered_bytes_start_empty: bool,
261}
262
263impl<W: Write> Serializer<W> {
264    /// Create a new serializer.
265    pub fn new(writer: QuickXmlWriter<W>) -> Self {
266        Self::new_with_namespaces(writer, BTreeMap::new())
267    }
268
269    /// Create a new serializer with preferred namespace prefixes.
270    pub fn new_with_namespaces(
271        writer: QuickXmlWriter<W>,
272        preferred_namespace_prefixes: BTreeMap<XmlNamespace<'static>, Prefix<'static>>,
273    ) -> Self {
274        Self {
275            writer,
276            preferred_namespace_prefixes,
277            namespace_scopes: NamespaceScopeContainer::new(),
278            buffered_bytes_start: BytesStart::new(""),
279            buffered_bytes_start_empty: true,
280        }
281    }
282
283    /// Consume the serializer and return the underlying writer.
284    pub fn into_inner(self) -> W {
285        self.writer.into_inner()
286    }
287
288    fn push_namespace_scope(&mut self) {
289        self.namespace_scopes.push_scope()
290    }
291
292    fn pop_namespace_scope(&mut self) {
293        self.namespace_scopes.pop_scope();
294    }
295
296    fn resolve_name<'b>(
297        &mut self,
298        name: ExpandedName<'b>,
299        preferred_prefix: Option<&Prefix<'b>>,
300        always_declare: IncludePrefix,
301    ) -> (QName<'static>, Option<XmlnsDeclaration<'static>>) {
302        let (local_name, namespace) = name.into_parts();
303
304        let namespace_ref = namespace.as_ref();
305
306        let preferred_prefix = preferred_prefix
307            .or_else(|| namespace_ref.and_then(|a| self.preferred_namespace_prefixes.get(a)));
308
309        self.namespace_scopes
310            .resolve_name(local_name, &namespace, preferred_prefix, always_declare)
311    }
312}
313
314impl<W: Write> From<QuickXmlWriter<W>> for Serializer<W> {
315    fn from(writer: QuickXmlWriter<W>) -> Self {
316        Self::new(writer)
317    }
318}
319
320impl<W: Write> From<W> for Serializer<W> {
321    fn from(writer: W) -> Self {
322        Self::new(QuickXmlWriter::new(writer))
323    }
324}
325
326/// The main element serializer for the `quick-xml` crate.
327pub struct SerializeElement<'s, W: Write> {
328    serializer: &'s mut Serializer<W>,
329    name: ExpandedName<'static>,
330    include_prefix: IncludePrefix,
331    preferred_prefix: Option<Prefix<'static>>,
332}
333
334impl<W: Write> SerializeElement<'_, W> {
335    fn resolve_name_or_declare<'a>(
336        name: ExpandedName<'a>,
337        preferred_prefix: Option<&Prefix<'a>>,
338        enforce_prefix: IncludePrefix,
339        serializer: &mut Serializer<W>,
340    ) -> (QName<'a>, Option<XmlnsDeclaration<'a>>) {
341        let (qname, decl) = serializer.resolve_name(name, preferred_prefix, enforce_prefix);
342
343        (qname, decl)
344    }
345}
346
347/// The attribute serializer for the `quick-xml` crate.
348pub struct AttributeSerializer<'t, W: Write> {
349    name: ExpandedName<'static>,
350    serializer: &'t mut Serializer<W>,
351    preferred_prefix: Option<Prefix<'static>>,
352    enforce_prefix: IncludePrefix,
353}
354
355/// The text serializer for the `quick-xml` crate. Used when serializing to an attribute value.
356pub struct TextSerializer {
357    value: Option<String>,
358}
359
360impl ser::SerializeSeq for &mut TextSerializer {
361    type Ok = ();
362    type Error = Error;
363
364    fn serialize_element<V: Serialize>(&mut self, value: &V) -> Result<Self::Ok, Self::Error> {
365        if self.value.is_some() {
366            return Err(Error::unexpected_serialize(Unexpected::Text));
367        }
368
369        let mut text_ser = TextSerializer { value: None };
370        value.serialize(&mut text_ser)?;
371
372        if let Some(value) = text_ser.value {
373            self.value = Some(value);
374        } else {
375            return Err(Error::unexpected_serialize(Unexpected::None));
376        }
377
378        Ok(())
379    }
380
381    fn end(self) -> Result<Self::Ok, Self::Error> {
382        Ok(())
383    }
384}
385
386impl<'a> ser::Serializer for &'a mut TextSerializer {
387    type Ok = ();
388    type Error = Error;
389
390    type SerializeElement = NoopDeSerializer<Self::Ok, Self::Error>;
391
392    type SerializeSeq = &'a mut TextSerializer;
393
394    fn serialize_text<S: AsRef<str>>(self, text: S) -> Result<(), Self::Error> {
395        if self.value.is_some() {
396            return Err(Error::unexpected_serialize(Unexpected::Text));
397        }
398
399        self.value = Some(text.as_ref().to_string());
400
401        Ok(())
402    }
403
404    fn serialize_cdata<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error> {
405        let _ = text;
406
407        Err(Error::unexpected_serialize(Unexpected::CData))
408    }
409
410    fn serialize_element(
411        self,
412        name: &'_ ExpandedName<'_>,
413    ) -> Result<Self::SerializeElement, Self::Error> {
414        let _ = name;
415
416        Err(Error::unexpected_serialize(Unexpected::Element))
417    }
418
419    fn serialize_seq(self) -> Result<Self::SerializeSeq, Self::Error> {
420        Ok(self)
421    }
422
423    fn serialize_decl<S: AsRef<str>>(
424        self,
425        version: S,
426        encoding: Option<S>,
427        standalone: Option<S>,
428    ) -> Result<Self::Ok, Self::Error> {
429        let _ = (version, encoding, standalone);
430
431        Err(Error::unexpected_serialize(Unexpected::Decl))
432    }
433
434    fn serialize_pi<S: AsRef<[u8]>>(self, target: S, content: S) -> Result<Self::Ok, Self::Error> {
435        let _ = (target, content);
436
437        Err(Error::unexpected_serialize(Unexpected::PI))
438    }
439
440    fn serialize_comment<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
441        let _ = text;
442
443        Err(Error::unexpected_serialize(Unexpected::Comment))
444    }
445
446    fn serialize_doctype<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
447        let _ = text;
448
449        Err(Error::unexpected_serialize(Unexpected::DocType))
450    }
451
452    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
453        Err(Error::unexpected_serialize(Unexpected::None))
454    }
455}
456
457impl<W: Write> ser::SerializeAttributeAccess for AttributeSerializer<'_, W> {
458    type Ok = ();
459    type Error = Error;
460
461    fn include_prefix(&mut self, should_enforce: IncludePrefix) -> Result<Self::Ok, Self::Error> {
462        self.enforce_prefix = should_enforce;
463        Ok(())
464    }
465
466    fn preferred_prefix(
467        &mut self,
468        preferred_prefix: Option<xmlity::Prefix<'_>>,
469    ) -> Result<Self::Ok, Self::Error> {
470        self.preferred_prefix = preferred_prefix.map(Prefix::into_owned);
471        Ok(())
472    }
473
474    fn end<S: Serialize>(self, value: &S) -> Result<Self::Ok, Self::Error> {
475        let (qname, decl) = SerializeElement::resolve_name_or_declare(
476            self.name,
477            self.preferred_prefix.as_ref(),
478            self.enforce_prefix,
479            self.serializer,
480        );
481
482        if let Some(decl) = decl {
483            self.serializer.push_decl_attr(decl);
484        }
485
486        let mut text_ser = TextSerializer { value: None };
487
488        value.serialize(&mut text_ser)?;
489
490        self.serializer.push_attr(
491            qname,
492            text_ser
493                .value
494                .expect("TextSerializer should have a value")
495                .into_bytes(),
496        );
497
498        Ok(())
499    }
500}
501
502impl<W: Write> ser::AttributeSerializer for &mut SerializeElementAttributes<'_, W> {
503    type Error = Error;
504
505    type Ok = ();
506    type SerializeAttribute<'a>
507        = AttributeSerializer<'a, W>
508    where
509        Self: 'a;
510
511    fn serialize_attribute(
512        &mut self,
513        name: &'_ ExpandedName<'_>,
514    ) -> Result<Self::SerializeAttribute<'_>, Self::Error> {
515        Ok(Self::SerializeAttribute {
516            name: name.clone().into_owned(),
517            serializer: self.serializer.deref_mut(),
518            preferred_prefix: None,
519            enforce_prefix: IncludePrefix::default(),
520        })
521    }
522
523    fn serialize_none(&mut self) -> Result<Self::Ok, Self::Error> {
524        Ok(())
525    }
526}
527
528impl<'s, W: Write> SerializeElement<'s, W> {
529    fn finish_start(self) -> (QName<'static>, &'s mut Serializer<W>) {
530        let Self {
531            name,
532            include_prefix,
533            preferred_prefix,
534            serializer,
535        } = self;
536
537        assert!(
538            serializer.buffered_bytes_start_empty,
539            "Should have been emptied by the serializer"
540        );
541
542        serializer.buffered_bytes_start.clear_attributes();
543
544        let (qname, decl) = SerializeElement::resolve_name_or_declare(
545            name.clone(),
546            preferred_prefix.as_ref(),
547            include_prefix,
548            serializer,
549        );
550        serializer
551            .buffered_bytes_start
552            .set_name(qname.to_string().as_bytes());
553
554        if let Some(decl) = decl {
555            serializer.push_decl_attr(decl);
556        }
557        serializer.buffered_bytes_start_empty = false;
558
559        (qname, serializer)
560    }
561
562    fn end_empty(serializer: &mut Serializer<W>) -> Result<(), Error> {
563        assert!(
564            !serializer.buffered_bytes_start_empty,
565            "start should be buffered"
566        );
567        let start = serializer.buffered_bytes_start.borrow();
568
569        serializer
570            .writer
571            .write_event(Event::Empty(start))
572            .map_err(Error::Io)?;
573
574        serializer.buffered_bytes_start_empty = true;
575
576        Ok(())
577    }
578}
579
580/// Provides the implementation of [`ser::SerializeElement`] for the `quick-xml` crate.
581pub struct SerializeElementAttributes<'s, W: Write> {
582    serializer: &'s mut Serializer<W>,
583    end_name: QName<'static>,
584}
585
586impl<W: Write> ser::SerializeAttributes for SerializeElementAttributes<'_, W> {
587    type Ok = ();
588    type Error = Error;
589
590    fn serialize_attribute<A: ser::SerializeAttribute>(
591        &mut self,
592        a: &A,
593    ) -> Result<Self::Ok, Self::Error> {
594        a.serialize_attribute(self)
595    }
596}
597
598impl<'s, W: Write> ser::SerializeElementAttributes for SerializeElementAttributes<'s, W> {
599    type ChildrenSerializeSeq = ChildrenSerializeSeq<'s, W>;
600
601    fn serialize_children(self) -> Result<Self::ChildrenSerializeSeq, Self::Error> {
602        Ok(ChildrenSerializeSeq {
603            serializer: self.serializer,
604            end_name: self.end_name,
605        })
606    }
607
608    fn end(self) -> Result<Self::Ok, Self::Error> {
609        SerializeElement::end_empty(self.serializer)
610    }
611}
612
613impl<'s, W: Write> ser::SerializeElement for SerializeElement<'s, W> {
614    type Ok = ();
615    type Error = Error;
616    type ChildrenSerializeSeq = ChildrenSerializeSeq<'s, W>;
617    type SerializeElementAttributes = SerializeElementAttributes<'s, W>;
618
619    fn include_prefix(&mut self, should_enforce: IncludePrefix) -> Result<Self::Ok, Self::Error> {
620        self.include_prefix = should_enforce;
621        Ok(())
622    }
623    fn preferred_prefix(
624        &mut self,
625        preferred_prefix: Option<Prefix<'_>>,
626    ) -> Result<Self::Ok, Self::Error> {
627        self.preferred_prefix = preferred_prefix.map(Prefix::into_owned);
628        Ok(())
629    }
630
631    fn serialize_attributes(self) -> Result<Self::SerializeElementAttributes, Self::Error> {
632        self.serializer.push_namespace_scope();
633        let (end_name, serializer) = self.finish_start();
634        Ok(SerializeElementAttributes {
635            serializer,
636            end_name,
637        })
638    }
639
640    fn serialize_children(self) -> Result<Self::ChildrenSerializeSeq, Self::Error> {
641        self.serializer.push_namespace_scope();
642        let (end_name, serializer) = self.finish_start();
643
644        Ok(ChildrenSerializeSeq {
645            serializer,
646            end_name,
647        })
648    }
649
650    fn end(self) -> Result<Self::Ok, Self::Error> {
651        self.serializer.push_namespace_scope();
652        let (_, serializer) = self.finish_start();
653
654        SerializeElement::end_empty(serializer)?;
655
656        serializer.pop_namespace_scope();
657
658        Ok(())
659    }
660}
661
662///Provides the implementation of `SerializeSeq` trait for element children for the `quick-xml` crate.
663pub struct ChildrenSerializeSeq<'s, W: Write> {
664    serializer: &'s mut Serializer<W>,
665    end_name: QName<'static>,
666}
667
668impl<W: Write> ser::SerializeSeq for ChildrenSerializeSeq<'_, W> {
669    type Ok = ();
670    type Error = Error;
671
672    fn serialize_element<V: Serialize>(&mut self, value: &V) -> Result<(), Self::Error> {
673        value.serialize(self.serializer.deref_mut())
674    }
675
676    fn end(self) -> Result<Self::Ok, Self::Error> {
677        // If we have a bytes_start, then we never wrote the start event, so we need to write an empty element instead.
678        if !self.serializer.buffered_bytes_start_empty {
679            self.serializer
680                .writer
681                .write_event(Event::Empty(self.serializer.buffered_bytes_start.borrow()))
682                .map_err(Error::Io)?;
683            self.serializer.buffered_bytes_start_empty = true;
684        } else {
685            let end_name = OwnedQuickName::new(&self.end_name);
686
687            let bytes_end = BytesEnd::from(end_name.as_ref());
688
689            self.serializer
690                .writer
691                .write_event(Event::End(bytes_end))
692                .map_err(Error::Io)?;
693        }
694
695        self.serializer.pop_namespace_scope();
696
697        Ok(())
698    }
699}
700
701/// Provides the implementation of `SerializeSeq` trait for any nodes for the `quick-xml` crate.
702pub struct SerializeSeq<'e, W: Write> {
703    serializer: &'e mut Serializer<W>,
704}
705
706impl<W: Write> ser::SerializeSeq for SerializeSeq<'_, W> {
707    type Ok = ();
708    type Error = Error;
709
710    fn serialize_element<V: Serialize>(&mut self, v: &V) -> Result<(), Self::Error> {
711        v.serialize(self.serializer.deref_mut())
712    }
713
714    fn end(self) -> Result<Self::Ok, Self::Error> {
715        Ok(())
716    }
717}
718
719impl<W: Write> Serializer<W> {
720    fn try_start(&mut self) -> Result<(), Error> {
721        if !self.buffered_bytes_start_empty {
722            self.writer
723                .write_event(Event::Start(self.buffered_bytes_start.borrow()))
724                .map_err(Error::Io)?;
725            self.buffered_bytes_start_empty = true;
726        }
727        Ok(())
728    }
729
730    fn push_attr(&mut self, qname: QName<'_>, value: Vec<u8>) {
731        self.buffered_bytes_start
732            .push_attribute(quick_xml::events::attributes::Attribute {
733                key: quick_xml::name::QName(qname.to_string().as_bytes()),
734                value: Cow::Owned(value),
735            });
736    }
737
738    fn push_decl_attr(&mut self, decl: XmlnsDeclaration<'_>) {
739        let XmlnsDeclaration { namespace, prefix } = decl;
740
741        let key = XmlnsDeclaration::xmlns_qname(prefix);
742
743        self.push_attr(key, namespace.as_str().as_bytes().to_vec());
744    }
745}
746
747impl<'s, W: Write> xmlity::Serializer for &'s mut Serializer<W> {
748    type Ok = ();
749    type Error = Error;
750    type SerializeElement = SerializeElement<'s, W>;
751    type SerializeSeq = SerializeSeq<'s, W>;
752
753    fn serialize_cdata<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error> {
754        self.try_start()?;
755        self.writer
756            .write_event(Event::CData(BytesCData::new(text.as_ref())))
757            .map_err(Error::Io)
758    }
759
760    fn serialize_text<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error> {
761        self.try_start()?;
762        self.writer
763            .write_event(Event::Text(BytesText::from_escaped(text.as_ref())))
764            .map_err(Error::Io)
765    }
766
767    fn serialize_element<'a>(
768        self,
769        name: &'a ExpandedName<'a>,
770    ) -> Result<Self::SerializeElement, Self::Error> {
771        self.try_start()?;
772
773        Ok(SerializeElement {
774            serializer: self,
775            name: name.clone().into_owned(),
776            include_prefix: IncludePrefix::default(),
777            preferred_prefix: None,
778        })
779    }
780
781    fn serialize_seq(self) -> Result<Self::SerializeSeq, Self::Error> {
782        Ok(SerializeSeq { serializer: self })
783    }
784
785    fn serialize_decl<S: AsRef<str>>(
786        self,
787        version: S,
788        encoding: Option<S>,
789        standalone: Option<S>,
790    ) -> Result<Self::Ok, Self::Error> {
791        self.try_start()?;
792        self.writer
793            .write_event(Event::Decl(BytesDecl::new(
794                version.as_ref(),
795                encoding.as_ref().map(|s| s.as_ref()),
796                standalone.as_ref().map(|s| s.as_ref()),
797            )))
798            .map_err(Error::Io)
799    }
800
801    fn serialize_pi<S: AsRef<[u8]>>(self, target: S, content: S) -> Result<Self::Ok, Self::Error> {
802        self.try_start()?;
803        self.writer
804            .write_event(Event::PI(BytesPI::new(format!(
805                "{} {}",
806                str::from_utf8(target.as_ref()).unwrap(),
807                str::from_utf8(content.as_ref()).unwrap()
808            ))))
809            .map_err(Error::Io)
810    }
811
812    fn serialize_comment<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
813        self.try_start()?;
814        self.writer
815            .write_event(Event::Comment(BytesText::from_escaped(
816                str::from_utf8(text.as_ref()).unwrap(),
817            )))
818            .map_err(Error::Io)
819    }
820
821    fn serialize_doctype<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
822        self.try_start()?;
823        self.writer
824            .write_event(Event::DocType(BytesText::from_escaped(
825                str::from_utf8(text.as_ref()).unwrap(),
826            )))
827            .map_err(Error::Io)
828    }
829
830    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
831        Ok(())
832    }
833}