1use std::collections::HashMap;
4use std::io::Write;
5
6use base64::Engine;
7use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
8use facet_core::{Def, Facet, Field, Shape, StructKind};
9use facet_reflect::{HasFields, Peek, is_spanned_shape};
10
11use crate::annotation::{XmlAnnotationPhase, fields_missing_xml_annotations};
12use crate::deserialize::{XmlFieldExt, XmlShapeExt};
13use crate::error::{MissingAnnotationPhase, XmlError, XmlErrorKind};
14
15pub type FloatFormatter = fn(f64, &mut dyn Write) -> std::io::Result<()>;
21
22#[derive(Clone)]
24pub struct SerializeOptions {
25 pub pretty: bool,
27 pub indent: &'static str,
29 pub float_formatter: Option<FloatFormatter>,
32 pub preserve_entities: bool,
65}
66
67impl Default for SerializeOptions {
68 fn default() -> Self {
69 Self {
70 pretty: false,
71 indent: " ",
72 float_formatter: None,
73 preserve_entities: false,
74 }
75 }
76}
77
78impl std::fmt::Debug for SerializeOptions {
79 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80 f.debug_struct("SerializeOptions")
81 .field("pretty", &self.pretty)
82 .field("indent", &self.indent)
83 .field("float_formatter", &self.float_formatter.map(|_| "..."))
84 .field("preserve_entities", &self.preserve_entities)
85 .finish()
86 }
87}
88
89impl SerializeOptions {
90 pub fn new() -> Self {
92 Self::default()
93 }
94
95 pub fn pretty(mut self) -> Self {
97 self.pretty = true;
98 self
99 }
100
101 pub fn indent(mut self, indent: &'static str) -> Self {
103 self.indent = indent;
104 self.pretty = true;
105 self
106 }
107
108 fn indent_str(&self) -> Option<&str> {
110 if self.pretty { Some(self.indent) } else { None }
111 }
112
113 pub fn float_formatter(mut self, formatter: FloatFormatter) -> Self {
146 self.float_formatter = Some(formatter);
147 self
148 }
149
150 pub fn preserve_entities(mut self, preserve: bool) -> Self {
177 self.preserve_entities = preserve;
178 self
179 }
180}
181
182const WELL_KNOWN_NAMESPACES: &[(&str, &str)] = &[
184 ("http://www.w3.org/2001/XMLSchema-instance", "xsi"),
185 ("http://www.w3.org/2001/XMLSchema", "xs"),
186 ("http://www.w3.org/XML/1998/namespace", "xml"),
187 ("http://www.w3.org/1999/xlink", "xlink"),
188 ("http://www.w3.org/2000/svg", "svg"),
189 ("http://www.w3.org/1999/xhtml", "xhtml"),
190 ("http://schemas.xmlsoap.org/soap/envelope/", "soap"),
191 ("http://www.w3.org/2003/05/soap-envelope", "soap12"),
192 ("http://schemas.android.com/apk/res/android", "android"),
193];
194
195pub(crate) type Result<T> = std::result::Result<T, XmlError>;
196
197pub fn to_string<T: Facet<'static>>(value: &T) -> Result<String> {
223 to_string_with_options(value, &SerializeOptions::default())
224}
225
226pub fn to_string_pretty<T: Facet<'static>>(value: &T) -> Result<String> {
251 to_string_with_options(value, &SerializeOptions::default().pretty())
252}
253
254pub fn to_string_with_options<T: Facet<'static>>(
283 value: &T,
284 options: &SerializeOptions,
285) -> Result<String> {
286 let mut output = Vec::new();
287 to_writer_with_options(&mut output, value, options)?;
288 Ok(String::from_utf8(output).expect("XML output should be valid UTF-8"))
289}
290
291pub fn to_writer<W: Write, T: Facet<'static>>(writer: &mut W, value: &T) -> Result<()> {
321 to_writer_with_options(writer, value, &SerializeOptions::default())
322}
323
324pub fn to_writer_pretty<W: Write, T: Facet<'static>>(writer: &mut W, value: &T) -> Result<()> {
351 to_writer_with_options(writer, value, &SerializeOptions::default().pretty())
352}
353
354pub fn to_writer_with_options<W: Write, T: Facet<'static>>(
389 writer: &mut W,
390 value: &T,
391 options: &SerializeOptions,
392) -> Result<()> {
393 let peek = Peek::new(value);
394 let mut serializer = XmlSerializer::new(
395 writer,
396 options.indent_str(),
397 options.float_formatter,
398 options.preserve_entities,
399 );
400
401 let type_name = crate::deserialize::get_shape_display_name(peek.shape());
403 serializer.serialize_element(type_name, peek)
404}
405
406struct XmlSerializer<'a, W> {
407 writer: W,
408 declared_namespaces: HashMap<String, String>,
410 next_ns_index: usize,
412 indent: Option<&'a str>,
414 depth: usize,
416 current_default_ns: Option<String>,
419 float_formatter: Option<FloatFormatter>,
421 preserve_entities: bool,
423}
424
425impl<'a, W: Write> XmlSerializer<'a, W> {
426 fn new(
427 writer: W,
428 indent: Option<&'a str>,
429 float_formatter: Option<FloatFormatter>,
430 preserve_entities: bool,
431 ) -> Self {
432 Self {
433 writer,
434 declared_namespaces: HashMap::new(),
435 next_ns_index: 0,
436 indent,
437 depth: 0,
438 current_default_ns: None,
439 float_formatter,
440 preserve_entities,
441 }
442 }
443
444 fn write_indent(&mut self) -> Result<()> {
446 if let Some(indent_str) = self.indent {
447 for _ in 0..self.depth {
448 self.writer
449 .write_all(indent_str.as_bytes())
450 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
451 }
452 }
453 Ok(())
454 }
455
456 fn write_newline(&mut self) -> Result<()> {
458 if self.indent.is_some() {
459 self.writer
460 .write_all(b"\n")
461 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
462 }
463 Ok(())
464 }
465
466 fn get_or_create_prefix(&mut self, namespace_uri: &str) -> String {
473 if let Some(prefix) = self.declared_namespaces.get(namespace_uri) {
475 return prefix.clone();
476 }
477
478 let prefix = WELL_KNOWN_NAMESPACES
480 .iter()
481 .find(|(uri, _)| *uri == namespace_uri)
482 .map(|(_, prefix)| (*prefix).to_string())
483 .unwrap_or_else(|| {
484 let prefix = format!("ns{}", self.next_ns_index);
486 self.next_ns_index += 1;
487 prefix
488 });
489
490 let final_prefix = if self.declared_namespaces.values().any(|p| p == &prefix) {
492 let prefix = format!("ns{}", self.next_ns_index);
494 self.next_ns_index += 1;
495 prefix
496 } else {
497 prefix
498 };
499
500 self.declared_namespaces
501 .insert(namespace_uri.to_string(), final_prefix.clone());
502 final_prefix
503 }
504
505 fn get_field_namespace(
514 field: &Field,
515 ns_all: Option<&'static str>,
516 is_attribute: bool,
517 ) -> Option<&'static str> {
518 if is_attribute {
519 field.xml_ns()
522 } else {
523 field.xml_ns().or(ns_all)
525 }
526 }
527
528 fn serialize_element<'mem, 'facet>(
529 &mut self,
530 element_name: &str,
531 peek: Peek<'mem, 'facet>,
532 ) -> Result<()> {
533 if let Ok(opt_peek) = peek.into_option() {
535 if opt_peek.is_none() {
536 return Ok(());
537 }
538 if let Some(inner) = opt_peek.value() {
539 return self.serialize_element(element_name, inner);
540 }
541 return Ok(());
542 }
543
544 if is_spanned_shape(peek.shape())
546 && let Ok(struct_peek) = peek.into_struct()
547 && let Ok(value_field) = struct_peek.field_by_name("value")
548 {
549 return self.serialize_element(element_name, value_field);
550 }
551
552 let shape = peek.shape();
554 if let Ok(struct_peek) = peek.into_struct() {
555 return self.serialize_struct_as_element(element_name, struct_peek, shape);
556 }
557
558 if let Ok(enum_peek) = peek.into_enum() {
560 return self.serialize_enum_as_element(element_name, enum_peek);
561 }
562
563 if self.try_serialize_bytes_as_element(element_name, peek)? {
565 return Ok(());
566 }
567
568 if let Ok(list_peek) = peek.into_list_like() {
570 return self.serialize_list_as_element(element_name, list_peek);
571 }
572
573 if let Ok(map_peek) = peek.into_map() {
575 return self.serialize_map_as_element(element_name, map_peek);
576 }
577
578 write!(self.writer, "<{}>", escape_element_name(element_name))
580 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
581 self.serialize_value(peek)?;
582 write!(self.writer, "</{}>", escape_element_name(element_name))
583 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
584
585 Ok(())
586 }
587
588 fn serialize_enum_as_element<'mem, 'facet>(
589 &mut self,
590 element_name: &str,
591 enum_peek: facet_reflect::PeekEnum<'mem, 'facet>,
592 ) -> Result<()> {
593 let shape = enum_peek.shape();
594 let variant_name = enum_peek
595 .variant_name_active()
596 .map_err(|_| XmlErrorKind::SerializeUnknownElementType)?;
597
598 let fields: Vec<_> = enum_peek.fields_for_serialize().collect();
599
600 let is_untagged = shape.is_untagged();
602 let tag_attr = shape.get_tag_attr();
603 let content_attr = shape.get_content_attr();
604
605 if is_untagged {
606 self.serialize_enum_content(element_name, variant_name, &fields)?;
608 } else if let Some(tag) = tag_attr {
609 if let Some(content) = content_attr {
610 write!(
612 self.writer,
613 "<{} {}=\"{}\">",
614 escape_element_name(element_name),
615 escape_element_name(tag),
616 escape_attribute_value(variant_name, self.preserve_entities)
617 )
618 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
619
620 if !fields.is_empty() {
621 write!(self.writer, "<{}>", escape_element_name(content))
623 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
624 self.serialize_variant_fields(&fields)?;
625 write!(self.writer, "</{}>", escape_element_name(content))
626 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
627 }
628
629 write!(self.writer, "</{}>", escape_element_name(element_name))
630 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
631 } else {
632 write!(
634 self.writer,
635 "<{} {}=\"{}\">",
636 escape_element_name(element_name),
637 escape_element_name(tag),
638 escape_attribute_value(variant_name, self.preserve_entities)
639 )
640 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
641
642 self.serialize_variant_fields(&fields)?;
644
645 write!(self.writer, "</{}>", escape_element_name(element_name))
646 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
647 }
648 } else {
649 write!(self.writer, "<{}>", escape_element_name(element_name))
651 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
652
653 if fields.is_empty() {
654 write!(self.writer, "<{}/>", escape_element_name(variant_name))
656 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
657 } else if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
658 self.serialize_element(variant_name, fields[0].1)?;
660 } else {
661 write!(self.writer, "<{}>", escape_element_name(variant_name))
663 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
664
665 for (field_item, field_peek) in fields {
666 self.serialize_element(&field_item.name, field_peek)?;
667 }
668
669 write!(self.writer, "</{}>", escape_element_name(variant_name))
670 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
671 }
672
673 write!(self.writer, "</{}>", escape_element_name(element_name))
674 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
675 }
676
677 Ok(())
678 }
679
680 fn serialize_enum_content<'mem, 'facet>(
682 &mut self,
683 element_name: &str,
684 variant_name: &str,
685 fields: &[(facet_reflect::FieldItem, Peek<'mem, 'facet>)],
686 ) -> Result<()> {
687 if fields.is_empty() {
688 write!(self.writer, "<{}/>", escape_element_name(element_name))
690 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
691 } else if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
692 self.serialize_element(element_name, fields[0].1)?;
694 } else {
695 write!(self.writer, "<{}>", escape_element_name(element_name))
697 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
698
699 for (field_item, field_peek) in fields {
700 let _ = variant_name; self.serialize_element(&field_item.name, *field_peek)?;
703 }
704
705 write!(self.writer, "</{}>", escape_element_name(element_name))
706 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
707 }
708 Ok(())
709 }
710
711 fn serialize_variant_fields<'mem, 'facet>(
713 &mut self,
714 fields: &[(facet_reflect::FieldItem, Peek<'mem, 'facet>)],
715 ) -> Result<()> {
716 if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
717 self.serialize_value(fields[0].1)?;
719 } else {
720 for (field_item, field_peek) in fields {
721 self.serialize_element(&field_item.name, *field_peek)?;
722 }
723 }
724 Ok(())
725 }
726
727 fn serialize_list_as_element<'mem, 'facet>(
728 &mut self,
729 element_name: &str,
730 list_peek: facet_reflect::PeekListLike<'mem, 'facet>,
731 ) -> Result<()> {
732 write!(self.writer, "<{}>", escape_element_name(element_name))
733 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
734
735 let has_items = list_peek.iter().next().is_some();
736 if has_items {
737 self.depth += 1;
738 }
739
740 for item in list_peek.iter() {
741 self.write_newline()?;
742 self.write_indent()?;
743 self.serialize_list_item_element(item)?;
744 }
745
746 if has_items {
747 self.depth -= 1;
748 self.write_newline()?;
749 self.write_indent()?;
750 }
751
752 write!(self.writer, "</{}>", escape_element_name(element_name))
753 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
754
755 Ok(())
756 }
757
758 fn serialize_map_as_element<'mem, 'facet>(
759 &mut self,
760 element_name: &str,
761 map_peek: facet_reflect::PeekMap<'mem, 'facet>,
762 ) -> Result<()> {
763 write!(self.writer, "<{}>", escape_element_name(element_name))
764 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
765
766 let has_items = map_peek.iter().next().is_some();
767 if has_items {
768 self.depth += 1;
769 }
770
771 for (key, value) in map_peek.iter() {
772 self.write_newline()?;
773 self.write_indent()?;
774 if let Some(key_str) = key.as_str() {
776 self.serialize_element(key_str, value)?;
777 } else if let Some(key_val) = value_to_string(key, self.float_formatter) {
778 self.serialize_element(&key_val, value)?;
779 } else {
780 write!(self.writer, "<entry>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
782 self.serialize_value(key)?;
783 self.serialize_value(value)?;
784 write!(self.writer, "</entry>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
785 }
786 }
787
788 if has_items {
789 self.depth -= 1;
790 self.write_newline()?;
791 self.write_indent()?;
792 }
793
794 write!(self.writer, "</{}>", escape_element_name(element_name))
795 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
796
797 Ok(())
798 }
799
800 fn try_serialize_bytes_as_element<'mem, 'facet>(
803 &mut self,
804 element_name: &str,
805 peek: Peek<'mem, 'facet>,
806 ) -> Result<bool> {
807 let shape = peek.shape();
808
809 if let Def::List(ld) = &shape.def
811 && ld.t().is_type::<u8>()
812 && let Some(bytes) = peek.as_bytes()
813 {
814 let encoded = BASE64_STANDARD.encode(bytes);
815 write!(self.writer, "<{}>", escape_element_name(element_name))
816 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
817 write!(
818 self.writer,
819 "{}",
820 escape_text(&encoded, self.preserve_entities)
821 )
822 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
823 write!(self.writer, "</{}>", escape_element_name(element_name))
824 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
825 return Ok(true);
826 }
827
828 if let Def::Array(ad) = &shape.def
830 && ad.t().is_type::<u8>()
831 {
832 if let Ok(list_peek) = peek.into_list_like() {
834 let bytes: Vec<u8> = list_peek
835 .iter()
836 .filter_map(|p| p.get::<u8>().ok().copied())
837 .collect();
838 let encoded = BASE64_STANDARD.encode(&bytes);
839 write!(self.writer, "<{}>", escape_element_name(element_name))
840 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
841 write!(
842 self.writer,
843 "{}",
844 escape_text(&encoded, self.preserve_entities)
845 )
846 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
847 write!(self.writer, "</{}>", escape_element_name(element_name))
848 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
849 return Ok(true);
850 }
851 }
852
853 if let Def::Slice(sd) = &shape.def
855 && sd.t().is_type::<u8>()
856 && let Some(bytes) = peek.as_bytes()
857 {
858 let encoded = BASE64_STANDARD.encode(bytes);
859 write!(self.writer, "<{}>", escape_element_name(element_name))
860 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
861 write!(
862 self.writer,
863 "{}",
864 escape_text(&encoded, self.preserve_entities)
865 )
866 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
867 write!(self.writer, "</{}>", escape_element_name(element_name))
868 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
869 return Ok(true);
870 }
871
872 Ok(false)
873 }
874
875 fn serialize_struct_as_element<'mem, 'facet>(
876 &mut self,
877 element_name: &str,
878 struct_peek: facet_reflect::PeekStruct<'mem, 'facet>,
879 shape: &'static Shape,
880 ) -> Result<()> {
881 let struct_ty = struct_peek.ty();
882
883 match struct_ty.kind {
884 StructKind::Unit => {
885 write!(self.writer, "<{}/>", escape_element_name(element_name))
887 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
888 return Ok(());
889 }
890 StructKind::Tuple | StructKind::TupleStruct => {
891 let fields: Vec<_> = struct_peek.fields_for_serialize().collect();
893 if fields.is_empty() {
894 write!(self.writer, "<{}/>", escape_element_name(element_name))
895 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
896 return Ok(());
897 }
898
899 write!(self.writer, "<{}>", escape_element_name(element_name))
900 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
901
902 for (i, (_, field_peek)) in fields.into_iter().enumerate() {
903 let field_name = format!("_{i}");
905 self.serialize_element(&field_name, field_peek)?;
906 }
907
908 write!(self.writer, "</{}>", escape_element_name(element_name))
909 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
910 return Ok(());
911 }
912 StructKind::Struct => {
913 }
915 }
916
917 let fields = struct_ty.fields;
918 let missing = fields_missing_xml_annotations(fields, XmlAnnotationPhase::Serialize);
919 if !missing.is_empty() {
920 let field_info = missing
921 .into_iter()
922 .map(|field| (field.name, field.shape().type_identifier))
923 .collect();
924 return Err(XmlError::new(XmlErrorKind::MissingXmlAnnotations {
925 type_name: shape.type_identifier,
926 phase: MissingAnnotationPhase::Serialize,
927 fields: field_info,
928 }));
929 }
930
931 let ns_all = shape.xml_ns_all();
933
934 struct AttrInfo {
936 name: String,
937 value: String,
938 namespace: Option<&'static str>,
939 }
940 let mut attributes: Vec<AttrInfo> = Vec::new();
941 let mut elements: Vec<(facet_reflect::FieldItem, Peek<'mem, 'facet>)> = Vec::new();
942 let mut elements_list: Vec<Peek<'mem, 'facet>> = Vec::new();
943 let mut text_content: Option<Peek<'mem, 'facet>> = None;
944
945 for (field_item, field_peek) in struct_peek.fields_for_serialize() {
946 let Some(field) = field_item.field else {
948 continue;
949 };
950
951 if field.is_xml_attribute() {
953 let value = if field.proxy_convert_out_fn().is_some() {
954 if let Ok(owned) = field_peek.custom_serialization(field) {
956 value_to_string(owned.as_peek(), self.float_formatter)
957 } else {
958 value_to_string(field_peek, self.float_formatter)
959 }
960 } else {
961 value_to_string(field_peek, self.float_formatter)
962 };
963 if let Some(value) = value {
964 let namespace = Self::get_field_namespace(&field, ns_all, true);
966 attributes.push(AttrInfo {
967 name: field_item.name.into_owned(),
968 value,
969 namespace,
970 });
971 }
972 } else if field.is_xml_element() {
973 elements.push((field_item, field_peek));
974 } else if field.is_xml_elements() {
975 elements_list.push(field_peek);
976 } else if field.is_xml_text() {
977 text_content = Some(field_peek);
978 }
979 }
980
981 let has_content =
983 !elements.is_empty() || !elements_list.is_empty() || text_content.is_some();
984
985 let mut xmlns_decls: Vec<(String, String)> = Vec::new(); let mut attr_prefixes: Vec<Option<String>> = Vec::new(); for attr in &attributes {
992 if let Some(ns_uri) = attr.namespace {
993 let prefix = self.get_or_create_prefix(ns_uri);
994 if !xmlns_decls.iter().any(|(_, u)| u == ns_uri) {
996 xmlns_decls.push((prefix.clone(), ns_uri.to_string()));
997 }
998 attr_prefixes.push(Some(prefix));
999 } else {
1000 attr_prefixes.push(None);
1001 }
1002 }
1003
1004 write!(self.writer, "<{}", escape_element_name(element_name))
1006 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1007
1008 let emitting_new_default_ns = if let Some(ns_uri) = ns_all {
1012 let dominated = self
1013 .current_default_ns
1014 .as_ref()
1015 .is_some_and(|current| current == ns_uri);
1016 if !dominated {
1017 write!(
1018 self.writer,
1019 " xmlns=\"{}\"",
1020 escape_attribute_value(ns_uri, self.preserve_entities)
1021 )
1022 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1023 true
1024 } else {
1025 false
1026 }
1027 } else {
1028 false
1029 };
1030
1031 for (prefix, uri) in &xmlns_decls {
1033 write!(
1034 self.writer,
1035 " xmlns:{}=\"{}\"",
1036 escape_element_name(prefix),
1037 escape_attribute_value(uri, self.preserve_entities)
1038 )
1039 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1040 }
1041
1042 for (attr, prefix) in attributes.iter().zip(attr_prefixes.iter()) {
1044 let attr_name = if let Some(p) = prefix {
1045 format!("{p}:{}", attr.name)
1046 } else {
1047 attr.name.to_string()
1048 };
1049 write!(
1050 self.writer,
1051 " {}=\"{}\"",
1052 escape_element_name(&attr_name),
1053 escape_attribute_value(&attr.value, self.preserve_entities)
1054 )
1055 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1056 }
1057
1058 if !has_content {
1059 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1061 return Ok(());
1062 }
1063
1064 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1065
1066 let old_default_ns = if emitting_new_default_ns {
1068 let old = self.current_default_ns.take();
1069 self.current_default_ns = ns_all.map(|s| s.to_string());
1070 old
1071 } else {
1072 None
1073 };
1074
1075 if let Some(text_peek) = text_content {
1077 self.serialize_text_value(text_peek)?;
1078 }
1079
1080 let has_child_elements = !elements.is_empty() || !elements_list.is_empty();
1082
1083 if has_child_elements {
1087 self.depth += 1;
1088 }
1089
1090 for (field_item, field_peek) in elements {
1091 let Some(field) = field_item.field else {
1093 continue;
1094 };
1095 let field_ns = Self::get_field_namespace(&field, ns_all, false);
1097
1098 self.write_newline()?;
1099 self.write_indent()?;
1100
1101 if field.proxy_convert_out_fn().is_some() {
1103 if let Ok(owned) = field_peek.custom_serialization(field) {
1104 self.serialize_namespaced_element(
1105 &field_item.name,
1106 owned.as_peek(),
1107 field_ns,
1108 ns_all,
1109 )?;
1110 } else {
1111 self.serialize_namespaced_element(
1112 &field_item.name,
1113 field_peek,
1114 field_ns,
1115 ns_all,
1116 )?;
1117 }
1118 } else {
1119 self.serialize_namespaced_element(&field_item.name, field_peek, field_ns, ns_all)?;
1120 }
1121 }
1122
1123 for field_peek in elements_list {
1125 self.serialize_elements_list(field_peek)?;
1126 }
1127
1128 if has_child_elements {
1129 self.depth -= 1;
1130 self.write_newline()?;
1131 self.write_indent()?;
1132 }
1133
1134 if emitting_new_default_ns {
1136 self.current_default_ns = old_default_ns;
1137 }
1138
1139 write!(self.writer, "</{}>", escape_element_name(element_name))
1141 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1142
1143 Ok(())
1144 }
1145
1146 fn serialize_namespaced_element<'mem, 'facet>(
1155 &mut self,
1156 element_name: &str,
1157 peek: Peek<'mem, 'facet>,
1158 namespace: Option<&str>,
1159 default_ns: Option<&str>,
1160 ) -> Result<()> {
1161 if let Ok(opt_peek) = peek.into_option() {
1163 if opt_peek.is_none() {
1164 return Ok(());
1165 }
1166 if let Some(inner) = opt_peek.value() {
1167 return self.serialize_namespaced_element(
1168 element_name,
1169 inner,
1170 namespace,
1171 default_ns,
1172 );
1173 }
1174 return Ok(());
1175 }
1176
1177 if is_spanned_shape(peek.shape())
1179 && let Ok(struct_peek) = peek.into_struct()
1180 && let Ok(value_field) = struct_peek.field_by_name("value")
1181 {
1182 return self.serialize_namespaced_element(
1183 element_name,
1184 value_field,
1185 namespace,
1186 default_ns,
1187 );
1188 }
1189
1190 let (final_name, xmlns_decl) = if let Some(ns_uri) = namespace {
1194 if default_ns == Some(ns_uri) {
1195 (element_name.to_string(), None)
1197 } else {
1198 let prefix = self.get_or_create_prefix(ns_uri);
1200 let prefixed = format!("{prefix}:{element_name}");
1201 (prefixed, Some((prefix, ns_uri.to_string())))
1202 }
1203 } else {
1204 (element_name.to_string(), None)
1205 };
1206
1207 let shape = peek.shape();
1209 if let Ok(struct_peek) = peek.into_struct() {
1210 return self.serialize_struct_as_namespaced_element(
1211 &final_name,
1212 struct_peek,
1213 xmlns_decl,
1214 shape,
1215 default_ns,
1216 );
1217 }
1218
1219 if let Ok(enum_peek) = peek.into_enum() {
1221 return self.serialize_enum_as_namespaced_element(&final_name, enum_peek, xmlns_decl);
1222 }
1223
1224 write!(self.writer, "<{}", escape_element_name(&final_name))
1226 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1227
1228 if let Some((prefix, uri)) = xmlns_decl {
1230 write!(
1231 self.writer,
1232 " xmlns:{}=\"{}\"",
1233 escape_element_name(&prefix),
1234 escape_attribute_value(&uri, self.preserve_entities)
1235 )
1236 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1237 }
1238
1239 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1240 self.serialize_value(peek)?;
1241 write!(self.writer, "</{}>", escape_element_name(&final_name))
1242 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1243
1244 Ok(())
1245 }
1246
1247 fn serialize_struct_as_namespaced_element<'mem, 'facet>(
1251 &mut self,
1252 element_name: &str,
1253 struct_peek: facet_reflect::PeekStruct<'mem, 'facet>,
1254 xmlns_decl: Option<(String, String)>,
1255 shape: &'static Shape,
1256 parent_default_ns: Option<&str>,
1257 ) -> Result<()> {
1258 match struct_peek.ty().kind {
1259 StructKind::Unit => {
1260 write!(self.writer, "<{}", escape_element_name(element_name))
1262 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1263 if let Some((prefix, uri)) = xmlns_decl {
1264 write!(
1265 self.writer,
1266 " xmlns:{}=\"{}\"",
1267 escape_element_name(&prefix),
1268 escape_attribute_value(&uri, self.preserve_entities)
1269 )
1270 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1271 }
1272 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1273 return Ok(());
1274 }
1275 StructKind::Tuple | StructKind::TupleStruct => {
1276 let fields: Vec<_> = struct_peek.fields_for_serialize().collect();
1278 if fields.is_empty() {
1279 write!(self.writer, "<{}", escape_element_name(element_name))
1280 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1281 if let Some((prefix, uri)) = xmlns_decl {
1282 write!(
1283 self.writer,
1284 " xmlns:{}=\"{}\"",
1285 escape_element_name(&prefix),
1286 escape_attribute_value(&uri, self.preserve_entities)
1287 )
1288 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1289 }
1290 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1291 return Ok(());
1292 }
1293
1294 write!(self.writer, "<{}", escape_element_name(element_name))
1295 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1296 if let Some((prefix, uri)) = xmlns_decl {
1297 write!(
1298 self.writer,
1299 " xmlns:{}=\"{}\"",
1300 escape_element_name(&prefix),
1301 escape_attribute_value(&uri, self.preserve_entities)
1302 )
1303 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1304 }
1305 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1306
1307 for (i, (_, field_peek)) in fields.into_iter().enumerate() {
1308 let field_name = format!("_{i}");
1309 self.serialize_element(&field_name, field_peek)?;
1310 }
1311
1312 write!(self.writer, "</{}>", escape_element_name(element_name))
1313 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1314 return Ok(());
1315 }
1316 StructKind::Struct => {
1317 }
1319 }
1320
1321 let ns_all = shape.xml_ns_all();
1323
1324 let effective_default_ns: Option<&str> = parent_default_ns;
1329
1330 struct AttrInfo {
1332 name: String,
1333 value: String,
1334 namespace: Option<&'static str>,
1335 }
1336 let mut attributes: Vec<AttrInfo> = Vec::new();
1337 let mut elements: Vec<(facet_reflect::FieldItem, Peek<'mem, 'facet>)> = Vec::new();
1338 let mut elements_list: Vec<Peek<'mem, 'facet>> = Vec::new();
1339 let mut text_content: Option<Peek<'mem, 'facet>> = None;
1340
1341 for (field_item, field_peek) in struct_peek.fields_for_serialize() {
1342 let Some(field) = field_item.field else {
1344 continue;
1345 };
1346
1347 if field.is_xml_attribute() {
1348 let value = if field.proxy_convert_out_fn().is_some() {
1349 if let Ok(owned) = field_peek.custom_serialization(field) {
1350 value_to_string(owned.as_peek(), self.float_formatter)
1351 } else {
1352 value_to_string(field_peek, self.float_formatter)
1353 }
1354 } else {
1355 value_to_string(field_peek, self.float_formatter)
1356 };
1357 if let Some(value) = value {
1358 let namespace = Self::get_field_namespace(&field, ns_all, true);
1360 attributes.push(AttrInfo {
1361 name: field_item.name.into_owned(),
1362 value,
1363 namespace,
1364 });
1365 }
1366 } else if field.is_xml_element() {
1367 elements.push((field_item, field_peek));
1368 } else if field.is_xml_elements() {
1369 elements_list.push(field_peek);
1370 } else if field.is_xml_text() {
1371 text_content = Some(field_peek);
1372 }
1373 }
1374
1375 let has_content =
1376 !elements.is_empty() || !elements_list.is_empty() || text_content.is_some();
1377
1378 let mut xmlns_decls: Vec<(String, String)> = Vec::new();
1381 let mut attr_prefixes: Vec<Option<String>> = Vec::new();
1382
1383 if let Some((prefix, uri)) = xmlns_decl {
1385 xmlns_decls.push((prefix, uri));
1386 }
1387
1388 for attr in &attributes {
1389 if let Some(ns_uri) = attr.namespace {
1390 let prefix = self.get_or_create_prefix(ns_uri);
1391 if !xmlns_decls.iter().any(|(_, u)| u == ns_uri) {
1393 xmlns_decls.push((prefix.clone(), ns_uri.to_string()));
1394 }
1395 attr_prefixes.push(Some(prefix));
1396 } else {
1397 attr_prefixes.push(None);
1398 }
1399 }
1400
1401 write!(self.writer, "<{}", escape_element_name(element_name))
1403 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1404
1405 for (prefix, uri) in &xmlns_decls {
1412 write!(
1413 self.writer,
1414 " xmlns:{}=\"{}\"",
1415 escape_element_name(prefix),
1416 escape_attribute_value(uri, self.preserve_entities)
1417 )
1418 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1419 }
1420
1421 for (attr, prefix) in attributes.iter().zip(attr_prefixes.iter()) {
1423 let attr_name = if let Some(p) = prefix {
1424 format!("{p}:{}", attr.name)
1425 } else {
1426 attr.name.to_string()
1427 };
1428 write!(
1429 self.writer,
1430 " {}=\"{}\"",
1431 escape_element_name(&attr_name),
1432 escape_attribute_value(&attr.value, self.preserve_entities)
1433 )
1434 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1435 }
1436
1437 if !has_content {
1438 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1439 return Ok(());
1440 }
1441
1442 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1443
1444 if let Some(text_peek) = text_content {
1445 self.serialize_text_value(text_peek)?;
1446 }
1447
1448 let has_child_elements = !elements.is_empty() || !elements_list.is_empty();
1450
1451 if has_child_elements {
1452 self.depth += 1;
1453 }
1454
1455 for (field_item, field_peek) in elements {
1456 let Some(field) = field_item.field else {
1458 continue;
1459 };
1460 let field_ns = Self::get_field_namespace(&field, ns_all, false);
1462
1463 self.write_newline()?;
1464 self.write_indent()?;
1465
1466 if field.proxy_convert_out_fn().is_some() {
1467 if let Ok(owned) = field_peek.custom_serialization(field) {
1468 self.serialize_namespaced_element(
1469 &field_item.name,
1470 owned.as_peek(),
1471 field_ns,
1472 effective_default_ns,
1473 )?;
1474 } else {
1475 self.serialize_namespaced_element(
1476 &field_item.name,
1477 field_peek,
1478 field_ns,
1479 effective_default_ns,
1480 )?;
1481 }
1482 } else {
1483 self.serialize_namespaced_element(
1484 &field_item.name,
1485 field_peek,
1486 field_ns,
1487 effective_default_ns,
1488 )?;
1489 }
1490 }
1491
1492 for field_peek in elements_list {
1493 self.serialize_elements_list(field_peek)?;
1494 }
1495
1496 if has_child_elements {
1497 self.depth -= 1;
1498 self.write_newline()?;
1499 self.write_indent()?;
1500 }
1501
1502 write!(self.writer, "</{}>", escape_element_name(element_name))
1503 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1504
1505 Ok(())
1506 }
1507
1508 fn serialize_enum_as_namespaced_element<'mem, 'facet>(
1510 &mut self,
1511 prefixed_element_name: &str,
1512 enum_peek: facet_reflect::PeekEnum<'mem, 'facet>,
1513 xmlns_decl: Option<(String, String)>,
1514 ) -> Result<()> {
1515 let shape = enum_peek.shape();
1516 let variant_name = enum_peek
1517 .variant_name_active()
1518 .map_err(|_| XmlErrorKind::SerializeUnknownElementType)?;
1519
1520 let fields: Vec<_> = enum_peek.fields_for_serialize().collect();
1521
1522 let is_untagged = shape.is_untagged();
1523 let tag_attr = shape.get_tag_attr();
1524 let content_attr = shape.get_content_attr();
1525
1526 let write_open_tag =
1528 |writer: &mut W, name: &str, xmlns: &Option<(String, String)>| -> Result<()> {
1529 write!(writer, "<{}", escape_element_name(name))
1530 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1531 if let Some((prefix, uri)) = xmlns {
1532 write!(
1533 writer,
1534 " xmlns:{}=\"{}\"",
1535 escape_element_name(prefix),
1536 escape_attribute_value(uri, self.preserve_entities)
1537 )
1538 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1539 }
1540 Ok(())
1541 };
1542
1543 if is_untagged {
1544 if fields.is_empty() {
1546 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1547 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1548 } else if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
1549 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1551 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1552 self.serialize_value(fields[0].1)?;
1553 write!(
1554 self.writer,
1555 "</{}>",
1556 escape_element_name(prefixed_element_name)
1557 )
1558 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1559 } else {
1560 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1561 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1562 for (field_item, field_peek) in fields {
1563 self.serialize_element(&field_item.name, field_peek)?;
1564 }
1565 write!(
1566 self.writer,
1567 "</{}>",
1568 escape_element_name(prefixed_element_name)
1569 )
1570 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1571 }
1572 } else if let Some(tag) = tag_attr {
1573 if let Some(content) = content_attr {
1574 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1576 write!(
1577 self.writer,
1578 " {}=\"{}\">",
1579 escape_element_name(tag),
1580 escape_attribute_value(variant_name, self.preserve_entities)
1581 )
1582 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1583
1584 if !fields.is_empty() {
1585 write!(self.writer, "<{}>", escape_element_name(content))
1586 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1587 self.serialize_variant_fields(&fields)?;
1588 write!(self.writer, "</{}>", escape_element_name(content))
1589 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1590 }
1591
1592 write!(
1593 self.writer,
1594 "</{}>",
1595 escape_element_name(prefixed_element_name)
1596 )
1597 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1598 } else {
1599 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1601 write!(
1602 self.writer,
1603 " {}=\"{}\">",
1604 escape_element_name(tag),
1605 escape_attribute_value(variant_name, self.preserve_entities)
1606 )
1607 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1608 self.serialize_variant_fields(&fields)?;
1609 write!(
1610 self.writer,
1611 "</{}>",
1612 escape_element_name(prefixed_element_name)
1613 )
1614 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1615 }
1616 } else {
1617 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1619 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1620
1621 if fields.is_empty() {
1622 write!(self.writer, "<{}/>", escape_element_name(variant_name))
1623 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1624 } else if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
1625 self.serialize_element(variant_name, fields[0].1)?;
1626 } else {
1627 write!(self.writer, "<{}>", escape_element_name(variant_name))
1628 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1629 for (field_item, field_peek) in fields {
1630 self.serialize_element(&field_item.name, field_peek)?;
1631 }
1632 write!(self.writer, "</{}>", escape_element_name(variant_name))
1633 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1634 }
1635
1636 write!(
1637 self.writer,
1638 "</{}>",
1639 escape_element_name(prefixed_element_name)
1640 )
1641 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1642 }
1643
1644 Ok(())
1645 }
1646
1647 fn serialize_elements_list<'mem, 'facet>(&mut self, peek: Peek<'mem, 'facet>) -> Result<()> {
1648 let list_peek = peek
1649 .into_list()
1650 .map_err(|_| XmlErrorKind::SerializeNotList)?;
1651
1652 for item_peek in list_peek.iter() {
1653 self.write_newline()?;
1654 self.write_indent()?;
1655 self.serialize_list_item_element(item_peek)?;
1656 }
1657
1658 Ok(())
1659 }
1660
1661 fn serialize_list_item_element<'mem, 'facet>(
1662 &mut self,
1663 peek: Peek<'mem, 'facet>,
1664 ) -> Result<()> {
1665 if let Ok(enum_peek) = peek.into_enum() {
1667 let variant_name = enum_peek
1668 .variant_name_active()
1669 .map_err(|_| XmlErrorKind::SerializeUnknownElementType)?;
1670
1671 let fields: Vec<_> = enum_peek.fields_for_serialize().collect();
1673
1674 if fields.is_empty() {
1675 write!(self.writer, "<{}/>", escape_element_name(variant_name))
1677 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1678 } else if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
1679 self.serialize_element(variant_name, fields[0].1)?;
1681 } else {
1682 write!(self.writer, "<{}>", escape_element_name(variant_name))
1684 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1685
1686 for (field_item, field_peek) in fields {
1687 self.serialize_element(&field_item.name, field_peek)?;
1688 }
1689
1690 write!(self.writer, "</{}>", escape_element_name(variant_name))
1691 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1692 }
1693 return Ok(());
1694 }
1695
1696 let type_name = peek.shape().type_identifier;
1698 self.serialize_element(type_name, peek)
1699 }
1700
1701 fn serialize_text_value<'mem, 'facet>(&mut self, peek: Peek<'mem, 'facet>) -> Result<()> {
1702 if let Ok(opt_peek) = peek.into_option() {
1704 if opt_peek.is_none() {
1705 return Ok(());
1706 }
1707 if let Some(inner) = opt_peek.value() {
1708 return self.serialize_text_value(inner);
1709 }
1710 return Ok(());
1711 }
1712
1713 if is_spanned_shape(peek.shape())
1715 && let Ok(struct_peek) = peek.into_struct()
1716 && let Ok(value_peek) = struct_peek.field_by_name("value")
1717 {
1718 return self.serialize_text_value(value_peek);
1719 }
1720
1721 self.serialize_value(peek)
1722 }
1723
1724 fn serialize_value<'mem, 'facet>(&mut self, peek: Peek<'mem, 'facet>) -> Result<()> {
1725 if let Ok(opt_peek) = peek.into_option() {
1727 if opt_peek.is_none() {
1728 return Ok(());
1729 }
1730 if let Some(inner) = opt_peek.value() {
1731 return self.serialize_value(inner);
1732 }
1733 return Ok(());
1734 }
1735
1736 if is_spanned_shape(peek.shape())
1738 && let Ok(struct_peek) = peek.into_struct()
1739 && let Ok(value_peek) = struct_peek.field_by_name("value")
1740 {
1741 return self.serialize_value(value_peek);
1742 }
1743
1744 let peek = peek.innermost_peek();
1746
1747 if let Some(s) = peek.as_str() {
1749 write!(self.writer, "{}", escape_text(s, self.preserve_entities))
1750 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1751 return Ok(());
1752 }
1753
1754 if let Ok(v) = peek.get::<bool>() {
1756 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1757 return Ok(());
1758 }
1759
1760 if let Ok(v) = peek.get::<i8>() {
1761 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1762 return Ok(());
1763 }
1764 if let Ok(v) = peek.get::<i16>() {
1765 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1766 return Ok(());
1767 }
1768 if let Ok(v) = peek.get::<i32>() {
1769 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1770 return Ok(());
1771 }
1772 if let Ok(v) = peek.get::<i64>() {
1773 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1774 return Ok(());
1775 }
1776
1777 if let Ok(v) = peek.get::<u8>() {
1778 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1779 return Ok(());
1780 }
1781 if let Ok(v) = peek.get::<u16>() {
1782 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1783 return Ok(());
1784 }
1785 if let Ok(v) = peek.get::<u32>() {
1786 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1787 return Ok(());
1788 }
1789 if let Ok(v) = peek.get::<u64>() {
1790 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1791 return Ok(());
1792 }
1793
1794 if let Ok(v) = peek.get::<f32>() {
1795 if let Some(fmt) = self.float_formatter {
1796 fmt(f64::from(*v), &mut self.writer)
1797 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1798 } else {
1799 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1800 }
1801 return Ok(());
1802 }
1803 if let Ok(v) = peek.get::<f64>() {
1804 if let Some(fmt) = self.float_formatter {
1805 fmt(*v, &mut self.writer).map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1806 } else {
1807 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1808 }
1809 return Ok(());
1810 }
1811
1812 if let Ok(v) = peek.get::<char>() {
1813 write!(
1814 self.writer,
1815 "{}",
1816 escape_text(&v.to_string(), self.preserve_entities)
1817 )
1818 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1819 return Ok(());
1820 }
1821
1822 Err(XmlErrorKind::SerializeUnknownValueType.into())
1823 }
1824}
1825
1826fn value_to_string<'mem, 'facet>(
1828 peek: Peek<'mem, 'facet>,
1829 float_formatter: Option<FloatFormatter>,
1830) -> Option<String> {
1831 if let Ok(opt_peek) = peek.into_option() {
1833 if opt_peek.is_none() {
1834 return None;
1835 }
1836 if let Some(inner) = opt_peek.value() {
1837 return value_to_string(inner, float_formatter);
1838 }
1839 return None;
1840 }
1841
1842 if is_spanned_shape(peek.shape())
1844 && let Ok(struct_peek) = peek.into_struct()
1845 && let Ok(value_peek) = struct_peek.field_by_name("value")
1846 {
1847 return value_to_string(value_peek, float_formatter);
1848 }
1849
1850 let peek = peek.innermost_peek();
1852
1853 if let Some(s) = peek.as_str() {
1855 return Some(s.to_string());
1856 }
1857
1858 if let Ok(v) = peek.get::<bool>() {
1860 return Some(v.to_string());
1861 }
1862
1863 if let Ok(v) = peek.get::<i8>() {
1864 return Some(v.to_string());
1865 }
1866 if let Ok(v) = peek.get::<i16>() {
1867 return Some(v.to_string());
1868 }
1869 if let Ok(v) = peek.get::<i32>() {
1870 return Some(v.to_string());
1871 }
1872 if let Ok(v) = peek.get::<i64>() {
1873 return Some(v.to_string());
1874 }
1875
1876 if let Ok(v) = peek.get::<u8>() {
1877 return Some(v.to_string());
1878 }
1879 if let Ok(v) = peek.get::<u16>() {
1880 return Some(v.to_string());
1881 }
1882 if let Ok(v) = peek.get::<u32>() {
1883 return Some(v.to_string());
1884 }
1885 if let Ok(v) = peek.get::<u64>() {
1886 return Some(v.to_string());
1887 }
1888
1889 if let Ok(v) = peek.get::<f32>() {
1890 if let Some(fmt) = float_formatter {
1891 let mut buf = Vec::new();
1892 if fmt(f64::from(*v), &mut buf).is_ok() {
1893 return String::from_utf8(buf).ok();
1894 }
1895 }
1896 return Some(v.to_string());
1897 }
1898 if let Ok(v) = peek.get::<f64>() {
1899 if let Some(fmt) = float_formatter {
1900 let mut buf = Vec::new();
1901 if fmt(*v, &mut buf).is_ok() {
1902 return String::from_utf8(buf).ok();
1903 }
1904 }
1905 return Some(v.to_string());
1906 }
1907
1908 if let Ok(v) = peek.get::<char>() {
1909 return Some(v.to_string());
1910 }
1911
1912 None
1913}
1914
1915fn escape_text(s: &str, preserve_entities: bool) -> String {
1917 if preserve_entities {
1918 escape_preserving_entities(s, false)
1919 } else {
1920 let mut result = String::with_capacity(s.len());
1921 for c in s.chars() {
1922 match c {
1923 '<' => result.push_str("<"),
1924 '>' => result.push_str(">"),
1925 '&' => result.push_str("&"),
1926 _ => result.push(c),
1927 }
1928 }
1929 result
1930 }
1931}
1932
1933fn escape_attribute_value(s: &str, preserve_entities: bool) -> String {
1935 if preserve_entities {
1936 escape_preserving_entities(s, true)
1937 } else {
1938 let mut result = String::with_capacity(s.len());
1939 for c in s.chars() {
1940 match c {
1941 '<' => result.push_str("<"),
1942 '>' => result.push_str(">"),
1943 '&' => result.push_str("&"),
1944 '"' => result.push_str("""),
1945 '\'' => result.push_str("'"),
1946 _ => result.push(c),
1947 }
1948 }
1949 result
1950 }
1951}
1952
1953fn escape_preserving_entities(s: &str, is_attribute: bool) -> String {
1960 let mut result = String::with_capacity(s.len());
1961 let chars: Vec<char> = s.chars().collect();
1962 let mut i = 0;
1963
1964 while i < chars.len() {
1965 let c = chars[i];
1966 match c {
1967 '<' => result.push_str("<"),
1968 '>' => result.push_str(">"),
1969 '"' if is_attribute => result.push_str("""),
1970 '\'' if is_attribute => result.push_str("'"),
1971 '&' => {
1972 if let Some(entity_len) = try_parse_entity_reference(&chars[i..]) {
1974 for j in 0..entity_len {
1976 result.push(chars[i + j]);
1977 }
1978 i += entity_len;
1979 continue;
1980 } else {
1981 result.push_str("&");
1983 }
1984 }
1985 _ => result.push(c),
1986 }
1987 i += 1;
1988 }
1989
1990 result
1991}
1992
1993fn try_parse_entity_reference(chars: &[char]) -> Option<usize> {
2001 if chars.is_empty() || chars[0] != '&' {
2002 return None;
2003 }
2004
2005 if chars.len() < 3 {
2007 return None;
2008 }
2009
2010 let mut len = 1; if chars[1] == '#' {
2013 len = 2;
2015
2016 if len < chars.len() && (chars[len] == 'x' || chars[len] == 'X') {
2017 len += 1;
2019 let start = len;
2020 while len < chars.len() && chars[len].is_ascii_hexdigit() {
2021 len += 1;
2022 }
2023 if len == start {
2025 return None;
2026 }
2027 } else {
2028 let start = len;
2030 while len < chars.len() && chars[len].is_ascii_digit() {
2031 len += 1;
2032 }
2033 if len == start {
2035 return None;
2036 }
2037 }
2038 } else {
2039 if !chars[len].is_ascii_alphabetic() && chars[len] != '_' {
2042 return None;
2043 }
2044 len += 1;
2045 while len < chars.len()
2046 && (chars[len].is_ascii_alphanumeric()
2047 || chars[len] == '_'
2048 || chars[len] == '-'
2049 || chars[len] == '.')
2050 {
2051 len += 1;
2052 }
2053 }
2054
2055 if len >= chars.len() || chars[len] != ';' {
2057 return None;
2058 }
2059
2060 Some(len + 1) }
2062
2063fn escape_element_name(name: &str) -> &str {
2065 name
2066}