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#[derive(Debug, thiserror::Error)]
20pub enum Error {
21 #[error("Quick XML error: {0}")]
23 QuickXml(#[from] quick_xml::Error),
24 #[error("Attribute error: {0}")]
26 AttrError(#[from] quick_xml::events::attributes::AttrError),
27 #[error("IO error: {0}")]
29 Io(#[from] std::io::Error),
30 #[error("Custom: {0}")]
32 Custom(String),
33 #[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
59pub 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
67pub 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 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 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 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 return (existing_prefix.clone(), None);
192 }
193 }
194
195 let prefix = preferred_prefix
198 .filter(|p| self.get_namespace(p).is_none_or(|n| n == namespace))
199 .or_else(|| {
201 preferred_prefix
202 .filter(|p| self.get_namespace(p).is_none_or(|n| n == namespace))
204 })
205 .cloned()
206 .unwrap_or_else(|| self.prefix_generator.new_prefix())
208 .into_owned();
209
210 let scope = self
211 .scopes
212 .last_mut()
213 .expect("There should be at least one scope");
214
215 scope
216 .defined_namespaces
217 .insert(prefix.clone(), namespace.clone().into_owned());
218
219 let (prefix, namespace) = scope
220 .defined_namespaces
221 .get_key_value(&prefix)
222 .expect("The namespace should be defined as it was just added");
223
224 let xmlns = XmlnsDeclaration::new(prefix.clone(), namespace.clone());
225
226 (prefix.clone(), Some(xmlns))
227 }
228
229 pub fn resolve_name<'c>(
230 &'c mut self,
231 local_name: LocalName<'c>,
232 namespace: &Option<XmlNamespace<'c>>,
233 preferred_prefix: Option<&'c Prefix<'c>>,
234 always_declare: IncludePrefix,
235 ) -> (QName<'a>, Option<XmlnsDeclaration<'a>>) {
236 let (prefix, declaration) = namespace
237 .as_ref()
238 .map(|namespace| self.resolve_namespace(namespace, preferred_prefix, always_declare))
239 .unzip();
240
241 let declaration = declaration.flatten();
242
243 let name = QName::new(prefix, local_name.into_owned());
244 (name, declaration)
245 }
246}
247
248pub struct Serializer<W: Write> {
250 writer: QuickXmlWriter<W>,
251 preferred_namespace_prefixes: BTreeMap<XmlNamespace<'static>, Prefix<'static>>,
252 namespace_scopes: NamespaceScopeContainer<'static>,
253 buffered_bytes_start: BytesStart<'static>,
254 buffered_bytes_start_empty: bool,
255}
256
257impl<W: Write> Serializer<W> {
258 pub fn new(writer: QuickXmlWriter<W>) -> Self {
260 Self::new_with_namespaces(writer, BTreeMap::new())
261 }
262
263 pub fn new_with_namespaces(
265 writer: QuickXmlWriter<W>,
266 preferred_namespace_prefixes: BTreeMap<XmlNamespace<'static>, Prefix<'static>>,
267 ) -> Self {
268 Self {
269 writer,
270 preferred_namespace_prefixes,
271 namespace_scopes: NamespaceScopeContainer::new(),
272 buffered_bytes_start: BytesStart::new(""),
273 buffered_bytes_start_empty: true,
274 }
275 }
276
277 pub fn into_inner(self) -> W {
279 self.writer.into_inner()
280 }
281
282 fn push_namespace_scope(&mut self) {
283 self.namespace_scopes.push_scope()
284 }
285
286 fn pop_namespace_scope(&mut self) {
287 self.namespace_scopes.pop_scope();
288 }
289
290 fn resolve_name<'b>(
291 &mut self,
292 name: ExpandedName<'b>,
293 preferred_prefix: Option<&Prefix<'b>>,
294 always_declare: IncludePrefix,
295 ) -> (QName<'static>, Option<XmlnsDeclaration<'static>>) {
296 let (local_name, namespace) = name.into_parts();
297
298 let namespace_ref = namespace.as_ref();
299
300 let preferred_prefix = preferred_prefix
301 .or_else(|| namespace_ref.and_then(|a| self.preferred_namespace_prefixes.get(a)));
302
303 self.namespace_scopes
304 .resolve_name(local_name, &namespace, preferred_prefix, always_declare)
305 }
306}
307
308impl<W: Write> From<QuickXmlWriter<W>> for Serializer<W> {
309 fn from(writer: QuickXmlWriter<W>) -> Self {
310 Self::new(writer)
311 }
312}
313
314impl<W: Write> From<W> for Serializer<W> {
315 fn from(writer: W) -> Self {
316 Self::new(QuickXmlWriter::new(writer))
317 }
318}
319
320pub struct SerializeElement<'s, W: Write> {
322 serializer: &'s mut Serializer<W>,
323 name: ExpandedName<'static>,
324 include_prefix: IncludePrefix,
325 preferred_prefix: Option<Prefix<'static>>,
326}
327
328impl<W: Write> SerializeElement<'_, W> {
329 fn resolve_name_or_declare<'a>(
330 name: ExpandedName<'a>,
331 preferred_prefix: Option<&Prefix<'a>>,
332 enforce_prefix: IncludePrefix,
333 serializer: &mut Serializer<W>,
334 ) -> (QName<'a>, Option<XmlnsDeclaration<'a>>) {
335 let (qname, decl) = serializer.resolve_name(name, preferred_prefix, enforce_prefix);
336
337 (qname, decl)
338 }
339}
340
341pub struct AttributeSerializer<'t, W: Write> {
343 name: ExpandedName<'static>,
344 serializer: &'t mut Serializer<W>,
345 preferred_prefix: Option<Prefix<'static>>,
346 enforce_prefix: IncludePrefix,
347}
348
349pub struct TextSerializer {
351 value: Vec<u8>,
352}
353
354impl ser::Serializer for &mut TextSerializer {
355 type Ok = ();
356 type Error = Error;
357
358 type SerializeElement = NoopDeSerializer<Self::Ok, Self::Error>;
359
360 type SerializeSeq = NoopDeSerializer<Self::Ok, Self::Error>;
361
362 fn serialize_text<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error> {
363 self.value.extend_from_slice(text.as_ref().as_bytes());
364
365 Ok(())
366 }
367
368 fn serialize_cdata<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error> {
369 let _ = text;
370
371 Err(Error::unexpected_serialize(Unexpected::CData))
372 }
373
374 fn serialize_element(
375 self,
376 name: &'_ ExpandedName<'_>,
377 ) -> Result<Self::SerializeElement, Self::Error> {
378 let _ = name;
379
380 Err(Error::unexpected_serialize(Unexpected::Element))
381 }
382
383 fn serialize_seq(self) -> Result<Self::SerializeSeq, Self::Error> {
384 Err(Error::unexpected_serialize(Unexpected::Seq))
385 }
386
387 fn serialize_decl<S: AsRef<str>>(
388 self,
389 version: S,
390 encoding: Option<S>,
391 standalone: Option<S>,
392 ) -> Result<Self::Ok, Self::Error> {
393 let _ = (version, encoding, standalone);
394
395 Err(Error::unexpected_serialize(Unexpected::Decl))
396 }
397
398 fn serialize_pi<S: AsRef<[u8]>>(self, target: S, content: S) -> Result<Self::Ok, Self::Error> {
399 let _ = (target, content);
400
401 Err(Error::unexpected_serialize(Unexpected::PI))
402 }
403
404 fn serialize_comment<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
405 let _ = text;
406
407 Err(Error::unexpected_serialize(Unexpected::Comment))
408 }
409
410 fn serialize_doctype<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
411 let _ = text;
412
413 Err(Error::unexpected_serialize(Unexpected::DocType))
414 }
415
416 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
417 Err(Error::unexpected_serialize(Unexpected::None))
418 }
419}
420
421impl<W: Write> ser::SerializeAttributeAccess for AttributeSerializer<'_, W> {
422 type Ok = ();
423 type Error = Error;
424
425 fn include_prefix(&mut self, should_enforce: IncludePrefix) -> Result<Self::Ok, Self::Error> {
426 self.enforce_prefix = should_enforce;
427 Ok(())
428 }
429
430 fn preferred_prefix(
431 &mut self,
432 preferred_prefix: Option<xmlity::Prefix<'_>>,
433 ) -> Result<Self::Ok, Self::Error> {
434 self.preferred_prefix = preferred_prefix.map(Prefix::into_owned);
435 Ok(())
436 }
437
438 fn end<S: Serialize>(self, value: &S) -> Result<Self::Ok, Self::Error> {
439 let (qname, decl) = SerializeElement::resolve_name_or_declare(
440 self.name,
441 self.preferred_prefix.as_ref(),
442 self.enforce_prefix,
443 self.serializer,
444 );
445
446 if let Some(decl) = decl {
447 self.serializer.push_decl_attr(decl);
448 }
449
450 let mut text_ser = TextSerializer { value: Vec::new() };
451
452 value.serialize(&mut text_ser)?;
453
454 self.serializer.push_attr(qname, text_ser.value);
455
456 Ok(())
457 }
458}
459
460impl<W: Write> ser::AttributeSerializer for &mut SerializeElementAttributes<'_, W> {
461 type Error = Error;
462
463 type Ok = ();
464 type SerializeAttribute<'a>
465 = AttributeSerializer<'a, W>
466 where
467 Self: 'a;
468
469 fn serialize_attribute(
470 &mut self,
471 name: &'_ ExpandedName<'_>,
472 ) -> Result<Self::SerializeAttribute<'_>, Self::Error> {
473 Ok(Self::SerializeAttribute {
474 name: name.clone().into_owned(),
475 serializer: self.serializer.deref_mut(),
476 preferred_prefix: None,
477 enforce_prefix: IncludePrefix::default(),
478 })
479 }
480
481 fn serialize_none(&mut self) -> Result<Self::Ok, Self::Error> {
482 Ok(())
483 }
484}
485
486impl<'s, W: Write> SerializeElement<'s, W> {
487 fn finish_start(self) -> (QName<'static>, &'s mut Serializer<W>) {
488 let Self {
489 name,
490 include_prefix,
491 preferred_prefix,
492 serializer,
493 } = self;
494
495 assert!(
496 serializer.buffered_bytes_start_empty,
497 "Should have been emptied by the serializer"
498 );
499
500 serializer.buffered_bytes_start.clear_attributes();
501
502 let (qname, decl) = SerializeElement::resolve_name_or_declare(
503 name.clone(),
504 preferred_prefix.as_ref(),
505 include_prefix,
506 serializer,
507 );
508 serializer
509 .buffered_bytes_start
510 .set_name(qname.to_string().as_bytes());
511
512 if let Some(decl) = decl {
513 serializer.push_decl_attr(decl);
514 }
515 serializer.buffered_bytes_start_empty = false;
516
517 (qname, serializer)
518 }
519
520 fn end_empty(serializer: &mut Serializer<W>) -> Result<(), Error> {
521 assert!(
522 !serializer.buffered_bytes_start_empty,
523 "start should be buffered"
524 );
525 let start = serializer.buffered_bytes_start.borrow();
526
527 serializer
528 .writer
529 .write_event(Event::Empty(start))
530 .map_err(Error::Io)?;
531
532 serializer.buffered_bytes_start_empty = true;
533
534 Ok(())
535 }
536}
537
538pub struct SerializeElementAttributes<'s, W: Write> {
540 serializer: &'s mut Serializer<W>,
541 end_name: QName<'static>,
542}
543
544impl<W: Write> ser::SerializeAttributes for SerializeElementAttributes<'_, W> {
545 type Ok = ();
546 type Error = Error;
547
548 fn serialize_attribute<A: ser::SerializeAttribute>(
549 &mut self,
550 a: &A,
551 ) -> Result<Self::Ok, Self::Error> {
552 a.serialize_attribute(self)
553 }
554}
555
556impl<'s, W: Write> ser::SerializeElementAttributes for SerializeElementAttributes<'s, W> {
557 type ChildrenSerializeSeq = ChildrenSerializeSeq<'s, W>;
558
559 fn serialize_children(self) -> Result<Self::ChildrenSerializeSeq, Self::Error> {
560 Ok(ChildrenSerializeSeq {
561 serializer: self.serializer,
562 end_name: self.end_name,
563 })
564 }
565
566 fn end(self) -> Result<Self::Ok, Self::Error> {
567 SerializeElement::end_empty(self.serializer)
568 }
569}
570
571impl<'s, W: Write> ser::SerializeElement for SerializeElement<'s, W> {
572 type Ok = ();
573 type Error = Error;
574 type ChildrenSerializeSeq = ChildrenSerializeSeq<'s, W>;
575 type SerializeElementAttributes = SerializeElementAttributes<'s, W>;
576
577 fn include_prefix(&mut self, should_enforce: IncludePrefix) -> Result<Self::Ok, Self::Error> {
578 self.include_prefix = should_enforce;
579 Ok(())
580 }
581 fn preferred_prefix(
582 &mut self,
583 preferred_prefix: Option<Prefix<'_>>,
584 ) -> Result<Self::Ok, Self::Error> {
585 self.preferred_prefix = preferred_prefix.map(Prefix::into_owned);
586 Ok(())
587 }
588
589 fn serialize_attributes(self) -> Result<Self::SerializeElementAttributes, Self::Error> {
590 self.serializer.push_namespace_scope();
591 let (end_name, serializer) = self.finish_start();
592 Ok(SerializeElementAttributes {
593 serializer,
594 end_name,
595 })
596 }
597
598 fn serialize_children(self) -> Result<Self::ChildrenSerializeSeq, Self::Error> {
599 self.serializer.push_namespace_scope();
600 let (end_name, serializer) = self.finish_start();
601
602 Ok(ChildrenSerializeSeq {
603 serializer,
604 end_name,
605 })
606 }
607
608 fn end(self) -> Result<Self::Ok, Self::Error> {
609 self.serializer.push_namespace_scope();
610 let (_, serializer) = self.finish_start();
611
612 SerializeElement::end_empty(serializer)?;
613
614 serializer.pop_namespace_scope();
615
616 Ok(())
617 }
618}
619
620pub struct ChildrenSerializeSeq<'s, W: Write> {
622 serializer: &'s mut Serializer<W>,
623 end_name: QName<'static>,
624}
625
626impl<W: Write> ser::SerializeSeq for ChildrenSerializeSeq<'_, W> {
627 type Ok = ();
628 type Error = Error;
629
630 fn serialize_element<V: Serialize>(&mut self, value: &V) -> Result<Self::Ok, Self::Error> {
631 value.serialize(self.serializer.deref_mut())
632 }
633
634 fn end(self) -> Result<Self::Ok, Self::Error> {
635 if !self.serializer.buffered_bytes_start_empty {
637 self.serializer
638 .writer
639 .write_event(Event::Empty(self.serializer.buffered_bytes_start.borrow()))
640 .map_err(Error::Io)?;
641 self.serializer.buffered_bytes_start_empty = true;
642 } else {
643 let end_name = OwnedQuickName::new(&self.end_name);
644
645 let bytes_end = BytesEnd::from(end_name.as_ref());
646
647 self.serializer
648 .writer
649 .write_event(Event::End(bytes_end))
650 .map_err(Error::Io)?;
651 }
652
653 self.serializer.pop_namespace_scope();
654
655 Ok(())
656 }
657}
658
659pub struct SerializeSeq<'e, W: Write> {
661 serializer: &'e mut Serializer<W>,
662}
663
664impl<W: Write> ser::SerializeSeq for SerializeSeq<'_, W> {
665 type Ok = ();
666 type Error = Error;
667
668 fn serialize_element<V: Serialize>(&mut self, v: &V) -> Result<Self::Ok, Self::Error> {
669 v.serialize(self.serializer.deref_mut())
670 }
671
672 fn end(self) -> Result<Self::Ok, Self::Error> {
673 Ok(())
674 }
675}
676
677impl<W: Write> Serializer<W> {
678 fn try_start(&mut self) -> Result<(), Error> {
679 if !self.buffered_bytes_start_empty {
680 self.writer
681 .write_event(Event::Start(self.buffered_bytes_start.borrow()))
682 .map_err(Error::Io)?;
683 self.buffered_bytes_start_empty = true;
684 }
685 Ok(())
686 }
687
688 fn push_attr(&mut self, qname: QName<'_>, value: Vec<u8>) {
689 self.buffered_bytes_start
690 .push_attribute(quick_xml::events::attributes::Attribute {
691 key: quick_xml::name::QName(qname.to_string().as_bytes()),
692 value: Cow::Owned(value),
693 });
694 }
695
696 fn push_decl_attr(&mut self, decl: XmlnsDeclaration<'_>) {
697 let XmlnsDeclaration { namespace, prefix } = decl;
698
699 let key = XmlnsDeclaration::xmlns_qname(prefix);
700
701 self.push_attr(key, namespace.as_str().as_bytes().to_vec());
702 }
703}
704
705impl<'s, W: Write> xmlity::Serializer for &'s mut Serializer<W> {
706 type Ok = ();
707 type Error = Error;
708 type SerializeElement = SerializeElement<'s, W>;
709 type SerializeSeq = SerializeSeq<'s, W>;
710
711 fn serialize_cdata<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error> {
712 self.try_start()?;
713 self.writer
714 .write_event(Event::CData(BytesCData::new(text.as_ref())))
715 .map_err(Error::Io)
716 }
717
718 fn serialize_text<S: AsRef<str>>(self, text: S) -> Result<Self::Ok, Self::Error> {
719 self.try_start()?;
720 self.writer
721 .write_event(Event::Text(BytesText::from_escaped(text.as_ref())))
722 .map_err(Error::Io)
723 }
724
725 fn serialize_element<'a>(
726 self,
727 name: &'a ExpandedName<'a>,
728 ) -> Result<Self::SerializeElement, Self::Error> {
729 self.try_start()?;
730
731 Ok(SerializeElement {
732 serializer: self,
733 name: name.clone().into_owned(),
734 include_prefix: IncludePrefix::default(),
735 preferred_prefix: None,
736 })
737 }
738
739 fn serialize_seq(self) -> Result<Self::SerializeSeq, Self::Error> {
740 Ok(SerializeSeq { serializer: self })
741 }
742
743 fn serialize_decl<S: AsRef<str>>(
744 self,
745 version: S,
746 encoding: Option<S>,
747 standalone: Option<S>,
748 ) -> Result<Self::Ok, Self::Error> {
749 self.try_start()?;
750 self.writer
751 .write_event(Event::Decl(BytesDecl::new(
752 version.as_ref(),
753 encoding.as_ref().map(|s| s.as_ref()),
754 standalone.as_ref().map(|s| s.as_ref()),
755 )))
756 .map_err(Error::Io)
757 }
758
759 fn serialize_pi<S: AsRef<[u8]>>(self, target: S, content: S) -> Result<Self::Ok, Self::Error> {
760 self.try_start()?;
761 self.writer
762 .write_event(Event::PI(BytesPI::new(format!(
763 "{} {}",
764 str::from_utf8(target.as_ref()).unwrap(),
765 str::from_utf8(content.as_ref()).unwrap()
766 ))))
767 .map_err(Error::Io)
768 }
769
770 fn serialize_comment<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
771 self.try_start()?;
772 self.writer
773 .write_event(Event::Comment(BytesText::from_escaped(
774 str::from_utf8(text.as_ref()).unwrap(),
775 )))
776 .map_err(Error::Io)
777 }
778
779 fn serialize_doctype<S: AsRef<[u8]>>(self, text: S) -> Result<Self::Ok, Self::Error> {
780 self.try_start()?;
781 self.writer
782 .write_event(Event::DocType(BytesText::from_escaped(
783 str::from_utf8(text.as_ref()).unwrap(),
784 )))
785 .map_err(Error::Io)
786 }
787
788 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
789 Ok(())
790 }
791}