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::ser::IncludePrefix;
11use xmlity::{ser, ExpandedName, Prefix, QName, Serialize, XmlNamespace};
12
13use crate::{declaration_into_attribute, Attribute, OwnedQuickName, XmlnsDeclaration};
14
15use super::Error;
16
17pub fn to_string<T>(value: &T) -> Result<String, Error>
18where
19    T: Serialize,
20{
21    let serializer = QuickXmlWriter::new(Vec::new());
22    let mut serializer = Serializer::from(serializer);
23    value.serialize(&mut serializer)?;
24    let bytes = serializer.into_inner();
25
26    String::from_utf8(bytes).map_err(Error::InvalidUtf8)
27}
28
29struct NamespaceScope<'a> {
30    pub defined_namespaces: BTreeMap<Prefix<'a>, XmlNamespace<'a>>,
31}
32
33impl<'a> NamespaceScope<'a> {
34    pub fn new() -> Self {
35        Self {
36            defined_namespaces: BTreeMap::new(),
37        }
38    }
39
40    pub fn get_namespace<'b>(&'b self, prefix: &'b Prefix<'b>) -> Option<&'b XmlNamespace<'a>> {
41        self.defined_namespaces.get(prefix)
42    }
43}
44
45struct NamespaceScopeContainer<'a> {
46    scopes: Vec<NamespaceScope<'a>>,
47    prefix_generator: PrefixGenerator,
48}
49
50struct PrefixGenerator {
51    count: usize,
52}
53
54impl PrefixGenerator {
55    pub fn index_to_name(index: usize) -> Prefix<'static> {
56        // 0 = a0
57        // 1 = a1
58        // 26 = b0
59        // 27 = b1
60        // 52 = c0
61        // 53 = c1
62        // ...
63
64        let letter = (index / 26) as u8 + b'a';
65        let number = (index % 26) as u8 + b'0';
66        let mut name = String::with_capacity(2);
67        name.push(letter as char);
68        name.push(number as char);
69        Prefix::new(name).expect("Invalid prefix generated")
70    }
71
72    pub fn new() -> Self {
73        Self { count: 0 }
74    }
75
76    pub fn new_prefix(&mut self) -> Prefix<'static> {
77        let name = Self::index_to_name(self.count);
78        self.count += 1;
79        name
80    }
81}
82
83impl<'a> NamespaceScopeContainer<'a> {
84    pub fn new() -> Self {
85        Self {
86            scopes: Vec::new(),
87            prefix_generator: PrefixGenerator::new(),
88        }
89    }
90
91    pub fn push_scope(&mut self) {
92        self.scopes.push(NamespaceScope::new())
93    }
94
95    pub fn pop_scope(&mut self) -> Option<NamespaceScope> {
96        self.scopes.pop()
97    }
98
99    pub fn get_namespace<'b>(&'b self, prefix: &'b Prefix<'b>) -> Option<&'b XmlNamespace<'a>> {
100        self.scopes
101            .iter()
102            .rev()
103            .find_map(|a| a.get_namespace(prefix))
104    }
105
106    /// Find matching prefix
107    pub fn find_matching_namespace<'b>(
108        &'b self,
109        namespace: &'b XmlNamespace<'b>,
110    ) -> Option<&'b Prefix<'a>> {
111        self.scopes.iter().rev().find_map(|a| {
112            a.defined_namespaces
113                .iter()
114                .find(|(_, found_namespace)| namespace == *found_namespace)
115                .map(|(prefix, _)| prefix)
116        })
117    }
118
119    /// 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.
120    pub fn resolve_namespace<'b>(
121        &'b mut self,
122        namespace: &'b XmlNamespace<'b>,
123        preferred_prefix: Option<&'b Prefix<'b>>,
124        always_declare: IncludePrefix,
125    ) -> (Prefix<'b>, Option<XmlnsDeclaration<'b>>) {
126        let existing_prefix = self
127            .find_matching_namespace(namespace)
128            // If we should always declare, we simply pretend it's not declared yet.
129            .filter(|_p| always_declare != IncludePrefix::Always);
130
131        if let Some(existing_prefix) = existing_prefix {
132            return (existing_prefix.clone(), None);
133        }
134
135        // If the namespace is not declared, use the specifically requested preferred prefix...
136        // ...if it is not already used and not the same as the existing prefix.
137        let prefix = preferred_prefix
138            .filter(|p| self.get_namespace(p).is_none_or(|n| n == namespace))
139            // If the preferred prefix is not available, use the preferred namespace prefix from the serializer...
140            .or_else(|| {
141                preferred_prefix
142                    // ...if it is not already used and not the same as the existing prefix.
143                    .filter(|p| self.get_namespace(p).is_none_or(|n| n == namespace))
144            })
145            .cloned()
146            // If the preferred namespace prefix is not available, use a random prefix.
147            .unwrap_or_else(|| self.prefix_generator.new_prefix());
148
149        let xmlns = XmlnsDeclaration::new(prefix.clone(), namespace.clone());
150
151        self.scopes.last_mut().map(|a| {
152            a.defined_namespaces
153                .insert(prefix.clone().into_owned(), namespace.clone().into_owned())
154        });
155
156        (prefix, Some(xmlns))
157    }
158
159    pub fn resolve_name<'b>(
160        &mut self,
161        name: ExpandedName<'b>,
162        preferred_prefix: Option<&Prefix<'b>>,
163        always_declare: IncludePrefix,
164    ) -> (QName<'b>, Option<XmlnsDeclaration<'b>>) {
165        let (prefix, declaration) = name
166            .namespace()
167            .map(|namespace| self.resolve_namespace(namespace, preferred_prefix, always_declare))
168            .unzip();
169
170        let declaration = declaration.flatten().map(|a| a.into_owned());
171        let resolved_prefix = prefix.map(|a| a.into_owned());
172
173        let name = name.to_q_name(resolved_prefix);
174        (name.into_owned(), declaration)
175    }
176}
177
178pub struct Serializer<W: Write> {
179    writer: QuickXmlWriter<W>,
180    preferred_namespace_prefixes: BTreeMap<XmlNamespace<'static>, Prefix<'static>>,
181    namespace_scopes: NamespaceScopeContainer<'static>,
182}
183
184impl<W: Write> Serializer<W> {
185    pub fn new(writer: QuickXmlWriter<W>) -> Self {
186        Self::new_with_namespaces(writer, BTreeMap::new())
187    }
188
189    pub fn new_with_namespaces(
190        writer: QuickXmlWriter<W>,
191        preferred_namespace_prefixes: BTreeMap<XmlNamespace<'static>, Prefix<'static>>,
192    ) -> Self {
193        Self {
194            writer,
195            preferred_namespace_prefixes,
196            namespace_scopes: NamespaceScopeContainer::new(),
197        }
198    }
199
200    pub fn into_inner(self) -> W {
201        self.writer.into_inner()
202    }
203
204    pub fn push_namespace_scope(&mut self) {
205        self.namespace_scopes.push_scope()
206    }
207
208    pub fn pop_namespace_scope(&mut self) {
209        self.namespace_scopes.pop_scope();
210    }
211
212    pub fn add_preferred_prefix(
213        &mut self,
214        namespace: XmlNamespace<'static>,
215        prefix: Prefix<'static>,
216    ) {
217        self.preferred_namespace_prefixes.insert(namespace, prefix);
218    }
219
220    pub fn resolve_name<'b>(
221        &mut self,
222        name: ExpandedName<'b>,
223        preferred_prefix: Option<&Prefix<'b>>,
224        always_declare: IncludePrefix,
225    ) -> (QName<'b>, Option<XmlnsDeclaration<'b>>) {
226        let name2 = name.clone();
227        let preferred_prefix = preferred_prefix.or_else(|| {
228            name2
229                .namespace()
230                .and_then(|a| self.preferred_namespace_prefixes.get(a))
231        });
232
233        self.namespace_scopes
234            .resolve_name(name, preferred_prefix, always_declare)
235    }
236}
237
238impl<W: Write> From<QuickXmlWriter<W>> for Serializer<W> {
239    fn from(writer: QuickXmlWriter<W>) -> Self {
240        Self::new(writer)
241    }
242}
243
244impl<W: Write> From<W> for Serializer<W> {
245    fn from(writer: W) -> Self {
246        Self::new(QuickXmlWriter::new(writer))
247    }
248}
249
250pub struct SerializeElement<'s, W: Write> {
251    serializer: &'s mut Serializer<W>,
252    name: ExpandedName<'static>,
253    attributes: Vec<Attribute<'static>>,
254    preferred_prefix: Option<Prefix<'static>>,
255    enforce_prefix: IncludePrefix,
256}
257
258pub struct AttributeSerializer<'t> {
259    name: ExpandedName<'static>,
260    on_end_add_to: &'t mut Vec<Attribute<'static>>,
261    preferred_prefix: Option<Prefix<'static>>,
262    enforce_prefix: IncludePrefix,
263}
264
265impl ser::SerializeAttributeAccess for AttributeSerializer<'_> {
266    type Ok = ();
267    type Error = Error;
268
269    fn include_prefix(&mut self, should_enforce: IncludePrefix) -> Result<Self::Ok, Self::Error> {
270        self.enforce_prefix = should_enforce;
271        Ok(())
272    }
273
274    fn preferred_prefix(
275        &mut self,
276        preferred_prefix: Option<xmlity::Prefix<'_>>,
277    ) -> Result<Self::Ok, Self::Error> {
278        self.preferred_prefix = preferred_prefix.map(Prefix::into_owned);
279        Ok(())
280    }
281
282    fn end<S: AsRef<str>>(self, value: S) -> Result<Self::Ok, Self::Error> {
283        self.on_end_add_to.push(Attribute {
284            name: self.name.into_owned(),
285            value: value.as_ref().to_owned(),
286            preferred_prefix: self.preferred_prefix,
287            enforce_prefix: self.enforce_prefix,
288        });
289
290        Ok(())
291    }
292}
293
294pub struct AttributeVecSerializer<'t> {
295    attributes: &'t mut Vec<Attribute<'static>>,
296}
297
298impl ser::AttributeSerializer for AttributeVecSerializer<'_> {
299    type Error = Error;
300
301    type Ok = ();
302    type SerializeAttribute<'a>
303        = AttributeSerializer<'a>
304    where
305        Self: 'a;
306
307    fn serialize_attribute(
308        &mut self,
309        name: &'_ ExpandedName<'_>,
310    ) -> Result<Self::SerializeAttribute<'_>, Self::Error> {
311        Ok(Self::SerializeAttribute {
312            name: name.clone().into_owned(),
313            on_end_add_to: &mut self.attributes,
314            preferred_prefix: None,
315            enforce_prefix: IncludePrefix::default(),
316        })
317    }
318
319    fn serialize_none(&mut self) -> Result<Self::Ok, Self::Error> {
320        Ok(())
321    }
322}
323
324/// This exists to allow us to transfer the practically completed BytesStart out of `finish_start` to then become the `quick_xml` BytesStart which is only exists by references to data.
325pub struct OwnedBytesStart {
326    name: OwnedQuickName,
327    attributes: Vec<(OwnedQuickName, Vec<u8>)>,
328}
329
330impl OwnedBytesStart {
331    pub fn as_quick_xml(&self) -> BytesStart<'_> {
332        BytesStart::from(self.name.as_ref()).with_attributes(self.attributes.iter().map(
333            |(key, value)| quick_xml::events::attributes::Attribute {
334                key: key.as_ref(),
335                value: Cow::Borrowed(value),
336            },
337        ))
338    }
339}
340
341impl<'s, W: Write> SerializeElement<'s, W> {
342    fn finish_start(self) -> (OwnedBytesStart, QName<'static>, &'s mut Serializer<W>) {
343        let Self {
344            serializer,
345            name,
346            attributes,
347            enforce_prefix,
348            preferred_prefix,
349        } = self;
350
351        let mut resolve_name_or_declare =
352            |name: &ExpandedName<'_>,
353             preferred_prefix: Option<&Prefix<'_>>,
354             enforce_prefix: IncludePrefix|
355             -> (QName<'static>, Option<XmlnsDeclaration<'static>>) {
356                let (qname, decl) =
357                    serializer.resolve_name(name.clone(), preferred_prefix, enforce_prefix);
358
359                (qname.into_owned(), decl.map(|a| a.into_owned()))
360            };
361
362        let (elem_qname, elem_name_decl) =
363            resolve_name_or_declare(&name, preferred_prefix.as_ref(), enforce_prefix);
364
365        let (attr_prefixes, attr_decls): (Vec<_>, Vec<_>) = attributes
366            .iter()
367            .map(|a| &a.name)
368            .map(|name| resolve_name_or_declare(name, None, IncludePrefix::default()))
369            .unzip();
370
371        let decls = elem_name_decl
372            .into_iter()
373            .chain(attr_decls.into_iter().flatten())
374            .collect::<Vec<_>>();
375
376        // Add declared namespaces first
377        let mut q_attributes = decls
378            .iter()
379            .map(|decl| declaration_into_attribute(decl.clone()))
380            .map(|attr| {
381                (
382                    OwnedQuickName::new(&attr.name),
383                    attr.value.as_bytes().to_owned(),
384                )
385            })
386            .collect::<Vec<_>>();
387
388        // Then add the attributes
389        q_attributes.extend(
390            attributes
391                .into_iter()
392                .zip(attr_prefixes)
393                .map(|(attr, qname)| attr.resolve(qname.prefix().cloned()))
394                .map(|attr| {
395                    (
396                        OwnedQuickName::new(&attr.name),
397                        attr.value.as_bytes().to_owned(),
398                    )
399                }),
400        );
401
402        let bytes_start = OwnedBytesStart {
403            name: OwnedQuickName::new(&elem_qname),
404            attributes: q_attributes,
405        };
406
407        (bytes_start, elem_qname, serializer)
408    }
409}
410
411impl<W: Write> ser::SerializeAttributes for SerializeElement<'_, W> {
412    type Ok = ();
413    type Error = Error;
414
415    fn serialize_attribute<A: ser::SerializeAttribute>(
416        &mut self,
417        a: &A,
418    ) -> Result<Self::Ok, Self::Error> {
419        a.serialize_attribute(AttributeVecSerializer {
420            attributes: &mut self.attributes,
421        })
422    }
423}
424
425impl<'s, W: Write> ser::SerializeElement for SerializeElement<'s, W> {
426    type SerializeElementChildren = SerializeElementChildren<'s, W>;
427
428    fn include_prefix(&mut self, should_enforce: IncludePrefix) -> Result<Self::Ok, Self::Error> {
429        self.enforce_prefix = should_enforce;
430        Ok(())
431    }
432    fn preferred_prefix(
433        &mut self,
434        preferred_prefix: Option<Prefix<'_>>,
435    ) -> Result<Self::Ok, Self::Error> {
436        self.preferred_prefix = preferred_prefix.map(Prefix::into_owned);
437        Ok(())
438    }
439
440    fn serialize_children(self) -> Result<Self::SerializeElementChildren, Self::Error> {
441        self.serializer.push_namespace_scope();
442        let (bytes_start, end_name, serializer) = self.finish_start();
443
444        serializer
445            .writer
446            .write_event(Event::Start(bytes_start.as_quick_xml()))
447            .map_err(Error::Io)?;
448
449        Ok(SerializeElementChildren {
450            serializer,
451            end_name,
452        })
453    }
454
455    fn end(self) -> Result<Self::Ok, Self::Error> {
456        self.serializer.push_namespace_scope();
457        let (bytes_start, _, serializer) = self.finish_start();
458
459        serializer
460            .writer
461            .write_event(Event::Empty(bytes_start.as_quick_xml()))
462            .map_err(Error::Io)?;
463
464        serializer.pop_namespace_scope();
465
466        Ok(())
467    }
468}
469
470pub struct SerializeElementChildren<'s, W: Write> {
471    serializer: &'s mut Serializer<W>,
472    end_name: QName<'static>,
473}
474
475impl<W: Write> ser::SerializeChildren for SerializeElementChildren<'_, W> {
476    type Ok = ();
477    type Error = Error;
478
479    fn serialize_child<V: Serialize>(&mut self, value: &V) -> Result<Self::Ok, Self::Error> {
480        value.serialize(self.serializer.deref_mut())
481    }
482}
483
484impl<W: Write> ser::SerializeElementChildren for SerializeElementChildren<'_, W> {
485    fn end(self) -> Result<Self::Ok, Self::Error> {
486        let end_name = OwnedQuickName::new(&self.end_name);
487
488        let bytes_end = BytesEnd::from(end_name.as_ref());
489
490        self.serializer
491            .writer
492            .write_event(Event::End(bytes_end))
493            .map_err(Error::Io)?;
494
495        self.serializer.pop_namespace_scope();
496
497        Ok(())
498    }
499}
500
501pub struct SerializeSeq<'e, W: Write> {
502    serializer: &'e mut Serializer<W>,
503}
504
505impl<W: Write> ser::SerializeSeq for SerializeSeq<'_, W> {
506    type Ok = ();
507    type Error = Error;
508
509    fn serialize_element<V: Serialize>(&mut self, v: &V) -> Result<Self::Ok, Self::Error> {
510        v.serialize(self.serializer.deref_mut())
511    }
512
513    fn end(self) -> Result<Self::Ok, Self::Error> {
514        Ok(())
515    }
516}
517
518impl<'s, W: Write> xmlity::Serializer for &'s mut Serializer<W> {
519    type Ok = ();
520    type Error = Error;
521    type SerializeElement = SerializeElement<'s, W>;
522    type SerializeSeq = SerializeSeq<'s, W>;
523
524    fn serialize_cdata<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error> {
525        self.writer
526            .write_event(Event::CData(BytesCData::new(text.as_ref())))
527            .map_err(Error::Io)
528    }
529
530    fn serialize_text<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error> {
531        self.writer
532            .write_event(Event::Text(BytesText::new(text.as_ref())))
533            .map_err(Error::Io)
534    }
535
536    fn serialize_element<'a>(
537        self,
538        name: &'a ExpandedName<'a>,
539    ) -> Result<Self::SerializeElement, Self::Error> {
540        Ok(SerializeElement {
541            serializer: self,
542            name: name.clone().into_owned(),
543            attributes: Vec::new(),
544            preferred_prefix: None,
545            enforce_prefix: IncludePrefix::default(),
546        })
547    }
548
549    fn serialize_seq(self) -> Result<Self::SerializeSeq, Self::Error> {
550        Ok(SerializeSeq { serializer: self })
551    }
552
553    fn serialize_decl<S: AsRef<str>>(
554        self,
555        version: S,
556        encoding: Option<S>,
557        standalone: Option<S>,
558    ) -> Result<Self::Ok, Self::Error> {
559        self.writer
560            .write_event(Event::Decl(BytesDecl::new(
561                version.as_ref(),
562                encoding.as_ref().map(|s| s.as_ref()),
563                standalone.as_ref().map(|s| s.as_ref()),
564            )))
565            .map_err(Error::Io)
566    }
567
568    fn serialize_pi<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
569        self.writer
570            .write_event(Event::PI(BytesPI::new(
571                str::from_utf8(text.as_ref()).unwrap(),
572            )))
573            .map_err(Error::Io)
574    }
575
576    fn serialize_comment<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
577        self.writer
578            .write_event(Event::Comment(BytesText::new(
579                str::from_utf8(text.as_ref()).unwrap(),
580            )))
581            .map_err(Error::Io)
582    }
583
584    fn serialize_doctype<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
585        self.writer
586            .write_event(Event::DocType(BytesText::new(
587                str::from_utf8(text.as_ref()).unwrap(),
588            )))
589            .map_err(Error::Io)
590    }
591
592    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
593        Ok(())
594    }
595}