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, LocalName, Prefix, QName, Serialize, XmlNamespace};
12
13use crate::{OwnedQuickName, XmlnsDeclaration};
14
15#[derive(Debug, thiserror::Error)]
17pub enum Error {
18 #[error("Quick XML error: {0}")]
20 QuickXml(#[from] quick_xml::Error),
21 #[error("Attribute error: {0}")]
23 AttrError(#[from] quick_xml::events::attributes::AttrError),
24 #[error("IO error: {0}")]
26 Io(#[from] std::io::Error),
27 #[error("Custom: {0}")]
29 Custom(String),
30 #[error("Invalid UTF-8: {0}")]
32 InvalidUtf8(#[from] std::string::FromUtf8Error),
33}
34
35impl xmlity::ser::Error for Error {
36 fn custom<T: ToString>(msg: T) -> Self {
37 Error::Custom(msg.to_string())
38 }
39}
40
41fn serializer_to_string<T>(serializer: QuickXmlWriter<Vec<u8>>, value: &T) -> Result<String, Error>
42where
43 T: Serialize,
44{
45 let mut serializer = Serializer::from(serializer);
46 value.serialize(&mut serializer)?;
47 let bytes = serializer.into_inner();
48
49 String::from_utf8(bytes).map_err(Error::InvalidUtf8)
50}
51
52pub fn to_string<T>(value: &T) -> Result<String, Error>
54where
55 T: Serialize,
56{
57 serializer_to_string(QuickXmlWriter::new(Vec::new()), value)
58}
59
60pub fn to_string_pretty<T>(value: &T, indentation: usize) -> Result<String, Error>
62where
63 T: Serialize,
64{
65 serializer_to_string(
66 QuickXmlWriter::new_with_indent(Vec::new(), b' ', indentation),
67 value,
68 )
69}
70
71struct NamespaceScope<'a> {
72 pub defined_namespaces: BTreeMap<Prefix<'a>, XmlNamespace<'a>>,
73}
74
75impl<'a> NamespaceScope<'a> {
76 pub fn new() -> Self {
77 Self {
78 defined_namespaces: BTreeMap::new(),
79 }
80 }
81
82 const XML_PREFIX: Prefix<'static> = Prefix::new_dangerous("xml");
83 const XML_NAMESPACE: XmlNamespace<'static> =
84 XmlNamespace::new_dangerous("http://www.w3.org/XML/1998/namespace");
85
86 pub fn top_scope() -> Self {
87 let mut scope = Self::new();
88 scope
89 .defined_namespaces
90 .insert(Self::XML_PREFIX, Self::XML_NAMESPACE);
91 scope
92 }
93
94 pub fn get_namespace<'b>(&'b self, prefix: &'b Prefix<'b>) -> Option<&'b XmlNamespace<'a>> {
95 self.defined_namespaces.get(prefix)
96 }
97}
98
99struct NamespaceScopeContainer<'a> {
100 scopes: Vec<NamespaceScope<'a>>,
101 prefix_generator: PrefixGenerator,
102}
103
104struct PrefixGenerator {
105 count: usize,
106}
107
108impl PrefixGenerator {
109 pub fn index_to_name(index: usize) -> Prefix<'static> {
110 let letter = (index / 26) as u8 + b'a';
119 let number = (index % 26) as u8 + b'0';
120 let mut name = String::with_capacity(2);
121 name.push(letter as char);
122 name.push(number as char);
123 Prefix::new(name).expect("Invalid prefix generated")
124 }
125
126 pub fn new() -> Self {
127 Self { count: 0 }
128 }
129
130 pub fn new_prefix(&mut self) -> Prefix<'static> {
131 let name = Self::index_to_name(self.count);
132 self.count += 1;
133 name
134 }
135}
136
137impl<'a> NamespaceScopeContainer<'a> {
138 pub fn new() -> Self {
139 Self {
140 scopes: vec![NamespaceScope::top_scope()],
141 prefix_generator: PrefixGenerator::new(),
142 }
143 }
144
145 pub fn push_scope(&mut self) {
146 self.scopes.push(NamespaceScope::new())
147 }
148
149 pub fn pop_scope(&mut self) -> Option<NamespaceScope> {
150 self.scopes.pop()
151 }
152
153 pub fn get_namespace<'b>(&'b self, prefix: &'b Prefix<'b>) -> Option<&'b XmlNamespace<'a>> {
154 self.scopes
155 .iter()
156 .rev()
157 .find_map(|a| a.get_namespace(prefix))
158 }
159
160 pub fn find_matching_namespace<'b>(
162 &'b self,
163 namespace: &'_ XmlNamespace<'_>,
164 ) -> Option<&'b Prefix<'a>> {
165 self.scopes.iter().rev().find_map(|a| {
166 a.defined_namespaces
167 .iter()
168 .find(|(_, found_namespace)| namespace == *found_namespace)
169 .map(|(prefix, _)| prefix)
170 })
171 }
172
173 pub fn resolve_namespace<'b>(
175 &'b mut self,
176 namespace: &'_ XmlNamespace<'b>,
177 preferred_prefix: Option<&'b Prefix<'b>>,
178 always_declare: IncludePrefix,
179 ) -> (Prefix<'a>, Option<XmlnsDeclaration<'a>>) {
180 if always_declare != IncludePrefix::Always {
181 let existing_prefix = self.find_matching_namespace(namespace);
182
183 if let Some(existing_prefix) = existing_prefix {
184 return (existing_prefix.clone(), None);
185 }
186 }
187
188 let prefix = preferred_prefix
191 .filter(|p| self.get_namespace(p).is_none_or(|n| n == namespace))
192 .or_else(|| {
194 preferred_prefix
195 .filter(|p| self.get_namespace(p).is_none_or(|n| n == namespace))
197 })
198 .cloned()
199 .unwrap_or_else(|| self.prefix_generator.new_prefix())
201 .into_owned();
202
203 let scope = self
204 .scopes
205 .last_mut()
206 .expect("There should be at least one scope");
207
208 scope
209 .defined_namespaces
210 .insert(prefix.clone(), namespace.clone().into_owned());
211
212 let (prefix, namespace) = scope
213 .defined_namespaces
214 .get_key_value(&prefix)
215 .expect("The namespace should be defined as it was just added");
216
217 let xmlns = XmlnsDeclaration::new(prefix.clone(), namespace.clone());
218
219 (prefix.clone(), Some(xmlns))
220 }
221
222 pub fn resolve_name<'c>(
223 &'c mut self,
224 local_name: LocalName<'c>,
225 namespace: &Option<XmlNamespace<'c>>,
226 preferred_prefix: Option<&'c Prefix<'c>>,
227 always_declare: IncludePrefix,
228 ) -> (QName<'a>, Option<XmlnsDeclaration<'a>>) {
229 let (prefix, declaration) = namespace
230 .as_ref()
231 .map(|namespace| self.resolve_namespace(namespace, preferred_prefix, always_declare))
232 .unzip();
233
234 let declaration = declaration.flatten();
235
236 let name = QName::new(prefix, local_name.into_owned());
237 (name, declaration)
238 }
239}
240
241pub struct Serializer<W: Write> {
243 writer: QuickXmlWriter<W>,
244 preferred_namespace_prefixes: BTreeMap<XmlNamespace<'static>, Prefix<'static>>,
245 namespace_scopes: NamespaceScopeContainer<'static>,
246 buffered_bytes_start: BytesStart<'static>,
247 buffered_bytes_start_empty: bool,
248}
249
250impl<W: Write> Serializer<W> {
251 pub fn new(writer: QuickXmlWriter<W>) -> Self {
253 Self::new_with_namespaces(writer, BTreeMap::new())
254 }
255
256 pub fn new_with_namespaces(
258 writer: QuickXmlWriter<W>,
259 preferred_namespace_prefixes: BTreeMap<XmlNamespace<'static>, Prefix<'static>>,
260 ) -> Self {
261 Self {
262 writer,
263 preferred_namespace_prefixes,
264 namespace_scopes: NamespaceScopeContainer::new(),
265 buffered_bytes_start: BytesStart::new(""),
266 buffered_bytes_start_empty: true,
267 }
268 }
269
270 pub fn into_inner(self) -> W {
272 self.writer.into_inner()
273 }
274
275 fn push_namespace_scope(&mut self) {
276 self.namespace_scopes.push_scope()
277 }
278
279 fn pop_namespace_scope(&mut self) {
280 self.namespace_scopes.pop_scope();
281 }
282
283 fn resolve_name<'b>(
284 &mut self,
285 name: ExpandedName<'b>,
286 preferred_prefix: Option<&Prefix<'b>>,
287 always_declare: IncludePrefix,
288 ) -> (QName<'static>, Option<XmlnsDeclaration<'static>>) {
289 let (local_name, namespace) = name.into_parts();
290
291 let namespace_ref = namespace.as_ref();
292
293 let preferred_prefix = preferred_prefix
294 .or_else(|| namespace_ref.and_then(|a| self.preferred_namespace_prefixes.get(a)));
295
296 self.namespace_scopes
297 .resolve_name(local_name, &namespace, preferred_prefix, always_declare)
298 }
299}
300
301impl<W: Write> From<QuickXmlWriter<W>> for Serializer<W> {
302 fn from(writer: QuickXmlWriter<W>) -> Self {
303 Self::new(writer)
304 }
305}
306
307impl<W: Write> From<W> for Serializer<W> {
308 fn from(writer: W) -> Self {
309 Self::new(QuickXmlWriter::new(writer))
310 }
311}
312
313pub struct SerializeElement<'s, W: Write> {
315 serializer: &'s mut Serializer<W>,
316 name: ExpandedName<'static>,
317 include_prefix: IncludePrefix,
318 preferred_prefix: Option<Prefix<'static>>,
319}
320
321impl<W: Write> SerializeElement<'_, W> {
322 fn resolve_name_or_declare<'a>(
323 name: ExpandedName<'a>,
324 preferred_prefix: Option<&Prefix<'a>>,
325 enforce_prefix: IncludePrefix,
326 serializer: &mut Serializer<W>,
327 ) -> (QName<'a>, Option<XmlnsDeclaration<'a>>) {
328 let (qname, decl) = serializer.resolve_name(name, preferred_prefix, enforce_prefix);
329
330 (qname, decl)
331 }
332}
333
334pub struct AttributeSerializer<'t, W: Write> {
336 name: ExpandedName<'static>,
337 serializer: &'t mut Serializer<W>,
338 preferred_prefix: Option<Prefix<'static>>,
339 enforce_prefix: IncludePrefix,
340}
341
342impl<W: Write> ser::SerializeAttributeAccess for AttributeSerializer<'_, W> {
343 type Ok = ();
344 type Error = Error;
345
346 fn include_prefix(&mut self, should_enforce: IncludePrefix) -> Result<Self::Ok, Self::Error> {
347 self.enforce_prefix = should_enforce;
348 Ok(())
349 }
350
351 fn preferred_prefix(
352 &mut self,
353 preferred_prefix: Option<xmlity::Prefix<'_>>,
354 ) -> Result<Self::Ok, Self::Error> {
355 self.preferred_prefix = preferred_prefix.map(Prefix::into_owned);
356 Ok(())
357 }
358
359 fn end<S: AsRef<str>>(self, value: S) -> Result<Self::Ok, Self::Error> {
360 let (qname, decl) = SerializeElement::resolve_name_or_declare(
361 self.name,
362 None,
363 IncludePrefix::default(),
364 self.serializer,
365 );
366
367 if let Some(decl) = decl {
368 self.serializer.push_decl_attr(decl);
369 }
370
371 self.serializer.push_attr(qname, value.as_ref());
372
373 Ok(())
374 }
375}
376
377impl<W: Write> ser::AttributeSerializer for &mut SerializeElementAttributes<'_, W> {
378 type Error = Error;
379
380 type Ok = ();
381 type SerializeAttribute<'a>
382 = AttributeSerializer<'a, W>
383 where
384 Self: 'a;
385
386 fn serialize_attribute(
387 &mut self,
388 name: &'_ ExpandedName<'_>,
389 ) -> Result<Self::SerializeAttribute<'_>, Self::Error> {
390 Ok(Self::SerializeAttribute {
391 name: name.clone().into_owned(),
392 serializer: self.serializer.deref_mut(),
393 preferred_prefix: None,
394 enforce_prefix: IncludePrefix::default(),
395 })
396 }
397
398 fn serialize_none(&mut self) -> Result<Self::Ok, Self::Error> {
399 Ok(())
400 }
401}
402
403impl<'s, W: Write> SerializeElement<'s, W> {
404 fn finish_start(self) -> (QName<'static>, &'s mut Serializer<W>) {
405 let Self {
406 name,
407 include_prefix,
408 preferred_prefix,
409 serializer,
410 } = self;
411
412 assert!(
413 serializer.buffered_bytes_start_empty,
414 "Should have been emptied by the serializer"
415 );
416
417 serializer.buffered_bytes_start.clear_attributes();
418
419 let (qname, decl) = SerializeElement::resolve_name_or_declare(
420 name.clone(),
421 preferred_prefix.as_ref(),
422 include_prefix,
423 serializer,
424 );
425 serializer
426 .buffered_bytes_start
427 .set_name(qname.to_string().as_bytes());
428
429 if let Some(decl) = decl {
430 serializer.push_decl_attr(decl);
431 }
432 serializer.buffered_bytes_start_empty = false;
433
434 (qname, serializer)
435 }
436
437 fn end_empty(serializer: &mut Serializer<W>) -> Result<(), Error> {
438 assert!(
439 !serializer.buffered_bytes_start_empty,
440 "start should be buffered"
441 );
442 let start = serializer.buffered_bytes_start.borrow();
443
444 serializer
445 .writer
446 .write_event(Event::Empty(start))
447 .map_err(Error::Io)?;
448
449 serializer.buffered_bytes_start_empty = true;
450
451 Ok(())
452 }
453}
454
455pub struct SerializeElementAttributes<'s, W: Write> {
457 serializer: &'s mut Serializer<W>,
458 end_name: QName<'static>,
459}
460
461impl<W: Write> ser::SerializeAttributes for SerializeElementAttributes<'_, W> {
462 type Ok = ();
463 type Error = Error;
464
465 fn serialize_attribute<A: ser::SerializeAttribute>(
466 &mut self,
467 a: &A,
468 ) -> Result<Self::Ok, Self::Error> {
469 a.serialize_attribute(self)
470 }
471}
472
473impl<'s, W: Write> ser::SerializeElementAttributes for SerializeElementAttributes<'s, W> {
474 type ChildrenSerializeSeq = ChildrenSerializeSeq<'s, W>;
475
476 fn serialize_children(self) -> Result<Self::ChildrenSerializeSeq, Self::Error> {
477 Ok(ChildrenSerializeSeq {
478 serializer: self.serializer,
479 end_name: self.end_name,
480 })
481 }
482
483 fn end(self) -> Result<Self::Ok, Self::Error> {
484 SerializeElement::end_empty(self.serializer)
485 }
486}
487
488impl<'s, W: Write> ser::SerializeElement for SerializeElement<'s, W> {
489 type Ok = ();
490 type Error = Error;
491 type ChildrenSerializeSeq = ChildrenSerializeSeq<'s, W>;
492 type SerializeElementAttributes = SerializeElementAttributes<'s, W>;
493
494 fn include_prefix(&mut self, should_enforce: IncludePrefix) -> Result<Self::Ok, Self::Error> {
495 self.include_prefix = should_enforce;
496 Ok(())
497 }
498 fn preferred_prefix(
499 &mut self,
500 preferred_prefix: Option<Prefix<'_>>,
501 ) -> Result<Self::Ok, Self::Error> {
502 self.preferred_prefix = preferred_prefix.map(Prefix::into_owned);
503 Ok(())
504 }
505
506 fn serialize_attributes(self) -> Result<Self::SerializeElementAttributes, Self::Error> {
507 self.serializer.push_namespace_scope();
508 let (end_name, serializer) = self.finish_start();
509 Ok(SerializeElementAttributes {
510 serializer,
511 end_name,
512 })
513 }
514
515 fn serialize_children(self) -> Result<Self::ChildrenSerializeSeq, Self::Error> {
516 self.serializer.push_namespace_scope();
517 let (end_name, serializer) = self.finish_start();
518
519 Ok(ChildrenSerializeSeq {
520 serializer,
521 end_name,
522 })
523 }
524
525 fn end(self) -> Result<Self::Ok, Self::Error> {
526 self.serializer.push_namespace_scope();
527 let (_, serializer) = self.finish_start();
528
529 SerializeElement::end_empty(serializer)?;
530
531 serializer.pop_namespace_scope();
532
533 Ok(())
534 }
535}
536
537pub struct ChildrenSerializeSeq<'s, W: Write> {
539 serializer: &'s mut Serializer<W>,
540 end_name: QName<'static>,
541}
542
543impl<W: Write> ser::SerializeSeq for ChildrenSerializeSeq<'_, W> {
544 type Ok = ();
545 type Error = Error;
546
547 fn serialize_element<V: Serialize>(&mut self, value: &V) -> Result<Self::Ok, Self::Error> {
548 value.serialize(self.serializer.deref_mut())
549 }
550
551 fn end(self) -> Result<Self::Ok, Self::Error> {
552 if !self.serializer.buffered_bytes_start_empty {
554 self.serializer
555 .writer
556 .write_event(Event::Empty(self.serializer.buffered_bytes_start.borrow()))
557 .map_err(Error::Io)?;
558 self.serializer.buffered_bytes_start_empty = true;
559 } else {
560 let end_name = OwnedQuickName::new(&self.end_name);
561
562 let bytes_end = BytesEnd::from(end_name.as_ref());
563
564 self.serializer
565 .writer
566 .write_event(Event::End(bytes_end))
567 .map_err(Error::Io)?;
568 }
569
570 self.serializer.pop_namespace_scope();
571
572 Ok(())
573 }
574}
575
576pub struct SerializeSeq<'e, W: Write> {
578 serializer: &'e mut Serializer<W>,
579}
580
581impl<W: Write> ser::SerializeSeq for SerializeSeq<'_, W> {
582 type Ok = ();
583 type Error = Error;
584
585 fn serialize_element<V: Serialize>(&mut self, v: &V) -> Result<Self::Ok, Self::Error> {
586 v.serialize(self.serializer.deref_mut())
587 }
588
589 fn end(self) -> Result<Self::Ok, Self::Error> {
590 Ok(())
591 }
592}
593
594impl<W: Write> Serializer<W> {
595 fn try_start(&mut self) -> Result<(), Error> {
596 if !self.buffered_bytes_start_empty {
597 self.writer
598 .write_event(Event::Start(self.buffered_bytes_start.borrow()))
599 .map_err(Error::Io)?;
600 self.buffered_bytes_start_empty = true;
601 }
602 Ok(())
603 }
604
605 fn push_attr(&mut self, qname: QName<'_>, value: &str) {
606 self.buffered_bytes_start
607 .push_attribute(quick_xml::events::attributes::Attribute {
608 key: quick_xml::name::QName(qname.to_string().as_bytes()),
609 value: Cow::Borrowed(value.as_bytes()),
610 });
611 }
612
613 fn push_decl_attr(&mut self, decl: XmlnsDeclaration<'_>) {
614 let XmlnsDeclaration { namespace, prefix } = decl;
615
616 let key = XmlnsDeclaration::xmlns_qname(prefix);
617
618 self.push_attr(key, namespace.as_str());
619 }
620}
621
622impl<'s, W: Write> xmlity::Serializer for &'s mut Serializer<W> {
623 type Ok = ();
624 type Error = Error;
625 type SerializeElement = SerializeElement<'s, W>;
626 type SerializeSeq = SerializeSeq<'s, W>;
627
628 fn serialize_cdata<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error> {
629 self.try_start()?;
630 self.writer
631 .write_event(Event::CData(BytesCData::new(text.as_ref())))
632 .map_err(Error::Io)
633 }
634
635 fn serialize_text<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error> {
636 self.try_start()?;
637 self.writer
638 .write_event(Event::Text(BytesText::from_escaped(text.as_ref())))
639 .map_err(Error::Io)
640 }
641
642 fn serialize_element<'a>(
643 self,
644 name: &'a ExpandedName<'a>,
645 ) -> Result<Self::SerializeElement, Self::Error> {
646 self.try_start()?;
647
648 Ok(SerializeElement {
649 serializer: self,
650 name: name.clone().into_owned(),
651 include_prefix: IncludePrefix::default(),
652 preferred_prefix: None,
653 })
654 }
655
656 fn serialize_seq(self) -> Result<Self::SerializeSeq, Self::Error> {
657 Ok(SerializeSeq { serializer: self })
658 }
659
660 fn serialize_decl<S: AsRef<str>>(
661 self,
662 version: S,
663 encoding: Option<S>,
664 standalone: Option<S>,
665 ) -> Result<Self::Ok, Self::Error> {
666 self.try_start()?;
667 self.writer
668 .write_event(Event::Decl(BytesDecl::new(
669 version.as_ref(),
670 encoding.as_ref().map(|s| s.as_ref()),
671 standalone.as_ref().map(|s| s.as_ref()),
672 )))
673 .map_err(Error::Io)
674 }
675
676 fn serialize_pi<S: AsRef<[u8]>>(self, target: S, content: S) -> Result<Self::Ok, Self::Error> {
677 self.try_start()?;
678 self.writer
679 .write_event(Event::PI(BytesPI::new(format!(
680 "{} {}",
681 str::from_utf8(target.as_ref()).unwrap(),
682 str::from_utf8(content.as_ref()).unwrap()
683 ))))
684 .map_err(Error::Io)
685 }
686
687 fn serialize_comment<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
688 self.try_start()?;
689 self.writer
690 .write_event(Event::Comment(BytesText::from_escaped(
691 str::from_utf8(text.as_ref()).unwrap(),
692 )))
693 .map_err(Error::Io)
694 }
695
696 fn serialize_doctype<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
697 self.try_start()?;
698 self.writer
699 .write_event(Event::DocType(BytesText::from_escaped(
700 str::from_utf8(text.as_ref()).unwrap(),
701 )))
702 .map_err(Error::Io)
703 }
704
705 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
706 Ok(())
707 }
708}