xmlity_quick_xml/
ser.rs

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