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