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<'a> {
936 name: &'a str,
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 field = &field_item.field;
947
948 if field.is_xml_attribute() {
950 let value = if field.proxy_convert_out_fn().is_some() {
951 if let Ok(owned) = field_peek.custom_serialization(*field) {
953 value_to_string(owned.as_peek(), self.float_formatter)
954 } else {
955 value_to_string(field_peek, self.float_formatter)
956 }
957 } else {
958 value_to_string(field_peek, self.float_formatter)
959 };
960 if let Some(value) = value {
961 let namespace = Self::get_field_namespace(field, ns_all, true);
963 attributes.push(AttrInfo {
964 name: field_item.name,
965 value,
966 namespace,
967 });
968 }
969 } else if field.is_xml_element() {
970 elements.push((field_item, field_peek));
971 } else if field.is_xml_elements() {
972 elements_list.push(field_peek);
973 } else if field.is_xml_text() {
974 text_content = Some(field_peek);
975 }
976 }
977
978 let has_content =
980 !elements.is_empty() || !elements_list.is_empty() || text_content.is_some();
981
982 let mut xmlns_decls: Vec<(String, String)> = Vec::new(); let mut attr_prefixes: Vec<Option<String>> = Vec::new(); for attr in &attributes {
989 if let Some(ns_uri) = attr.namespace {
990 let prefix = self.get_or_create_prefix(ns_uri);
991 if !xmlns_decls.iter().any(|(_, u)| u == ns_uri) {
993 xmlns_decls.push((prefix.clone(), ns_uri.to_string()));
994 }
995 attr_prefixes.push(Some(prefix));
996 } else {
997 attr_prefixes.push(None);
998 }
999 }
1000
1001 write!(self.writer, "<{}", escape_element_name(element_name))
1003 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1004
1005 let emitting_new_default_ns = if let Some(ns_uri) = ns_all {
1009 let dominated = self
1010 .current_default_ns
1011 .as_ref()
1012 .is_some_and(|current| current == ns_uri);
1013 if !dominated {
1014 write!(
1015 self.writer,
1016 " xmlns=\"{}\"",
1017 escape_attribute_value(ns_uri, self.preserve_entities)
1018 )
1019 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1020 true
1021 } else {
1022 false
1023 }
1024 } else {
1025 false
1026 };
1027
1028 for (prefix, uri) in &xmlns_decls {
1030 write!(
1031 self.writer,
1032 " xmlns:{}=\"{}\"",
1033 escape_element_name(prefix),
1034 escape_attribute_value(uri, self.preserve_entities)
1035 )
1036 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1037 }
1038
1039 for (attr, prefix) in attributes.iter().zip(attr_prefixes.iter()) {
1041 let attr_name = if let Some(p) = prefix {
1042 format!("{p}:{}", attr.name)
1043 } else {
1044 attr.name.to_string()
1045 };
1046 write!(
1047 self.writer,
1048 " {}=\"{}\"",
1049 escape_element_name(&attr_name),
1050 escape_attribute_value(&attr.value, self.preserve_entities)
1051 )
1052 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1053 }
1054
1055 if !has_content {
1056 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1058 return Ok(());
1059 }
1060
1061 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1062
1063 let old_default_ns = if emitting_new_default_ns {
1065 let old = self.current_default_ns.take();
1066 self.current_default_ns = ns_all.map(|s| s.to_string());
1067 old
1068 } else {
1069 None
1070 };
1071
1072 if let Some(text_peek) = text_content {
1074 self.serialize_text_value(text_peek)?;
1075 }
1076
1077 let has_child_elements = !elements.is_empty() || !elements_list.is_empty();
1079
1080 if has_child_elements {
1084 self.depth += 1;
1085 }
1086
1087 for (field_item, field_peek) in elements {
1088 let field_ns = Self::get_field_namespace(&field_item.field, ns_all, false);
1090
1091 self.write_newline()?;
1092 self.write_indent()?;
1093
1094 if field_item.field.proxy_convert_out_fn().is_some() {
1096 if let Ok(owned) = field_peek.custom_serialization(field_item.field) {
1097 self.serialize_namespaced_element(
1098 field_item.name,
1099 owned.as_peek(),
1100 field_ns,
1101 ns_all,
1102 )?;
1103 } else {
1104 self.serialize_namespaced_element(
1105 field_item.name,
1106 field_peek,
1107 field_ns,
1108 ns_all,
1109 )?;
1110 }
1111 } else {
1112 self.serialize_namespaced_element(field_item.name, field_peek, field_ns, ns_all)?;
1113 }
1114 }
1115
1116 for field_peek in elements_list {
1118 self.serialize_elements_list(field_peek)?;
1119 }
1120
1121 if has_child_elements {
1122 self.depth -= 1;
1123 self.write_newline()?;
1124 self.write_indent()?;
1125 }
1126
1127 if emitting_new_default_ns {
1129 self.current_default_ns = old_default_ns;
1130 }
1131
1132 write!(self.writer, "</{}>", escape_element_name(element_name))
1134 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1135
1136 Ok(())
1137 }
1138
1139 fn serialize_namespaced_element<'mem, 'facet>(
1148 &mut self,
1149 element_name: &str,
1150 peek: Peek<'mem, 'facet>,
1151 namespace: Option<&str>,
1152 default_ns: Option<&str>,
1153 ) -> Result<()> {
1154 if let Ok(opt_peek) = peek.into_option() {
1156 if opt_peek.is_none() {
1157 return Ok(());
1158 }
1159 if let Some(inner) = opt_peek.value() {
1160 return self.serialize_namespaced_element(
1161 element_name,
1162 inner,
1163 namespace,
1164 default_ns,
1165 );
1166 }
1167 return Ok(());
1168 }
1169
1170 if is_spanned_shape(peek.shape())
1172 && let Ok(struct_peek) = peek.into_struct()
1173 && let Ok(value_field) = struct_peek.field_by_name("value")
1174 {
1175 return self.serialize_namespaced_element(
1176 element_name,
1177 value_field,
1178 namespace,
1179 default_ns,
1180 );
1181 }
1182
1183 let (final_name, xmlns_decl) = if let Some(ns_uri) = namespace {
1187 if default_ns == Some(ns_uri) {
1188 (element_name.to_string(), None)
1190 } else {
1191 let prefix = self.get_or_create_prefix(ns_uri);
1193 let prefixed = format!("{prefix}:{element_name}");
1194 (prefixed, Some((prefix, ns_uri.to_string())))
1195 }
1196 } else {
1197 (element_name.to_string(), None)
1198 };
1199
1200 let shape = peek.shape();
1202 if let Ok(struct_peek) = peek.into_struct() {
1203 return self.serialize_struct_as_namespaced_element(
1204 &final_name,
1205 struct_peek,
1206 xmlns_decl,
1207 shape,
1208 default_ns,
1209 );
1210 }
1211
1212 if let Ok(enum_peek) = peek.into_enum() {
1214 return self.serialize_enum_as_namespaced_element(&final_name, enum_peek, xmlns_decl);
1215 }
1216
1217 write!(self.writer, "<{}", escape_element_name(&final_name))
1219 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1220
1221 if let Some((prefix, uri)) = xmlns_decl {
1223 write!(
1224 self.writer,
1225 " xmlns:{}=\"{}\"",
1226 escape_element_name(&prefix),
1227 escape_attribute_value(&uri, self.preserve_entities)
1228 )
1229 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1230 }
1231
1232 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1233 self.serialize_value(peek)?;
1234 write!(self.writer, "</{}>", escape_element_name(&final_name))
1235 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1236
1237 Ok(())
1238 }
1239
1240 fn serialize_struct_as_namespaced_element<'mem, 'facet>(
1244 &mut self,
1245 element_name: &str,
1246 struct_peek: facet_reflect::PeekStruct<'mem, 'facet>,
1247 xmlns_decl: Option<(String, String)>,
1248 shape: &'static Shape,
1249 parent_default_ns: Option<&str>,
1250 ) -> Result<()> {
1251 match struct_peek.ty().kind {
1252 StructKind::Unit => {
1253 write!(self.writer, "<{}", escape_element_name(element_name))
1255 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1256 if let Some((prefix, uri)) = xmlns_decl {
1257 write!(
1258 self.writer,
1259 " xmlns:{}=\"{}\"",
1260 escape_element_name(&prefix),
1261 escape_attribute_value(&uri, self.preserve_entities)
1262 )
1263 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1264 }
1265 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1266 return Ok(());
1267 }
1268 StructKind::Tuple | StructKind::TupleStruct => {
1269 let fields: Vec<_> = struct_peek.fields_for_serialize().collect();
1271 if fields.is_empty() {
1272 write!(self.writer, "<{}", escape_element_name(element_name))
1273 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1274 if let Some((prefix, uri)) = xmlns_decl {
1275 write!(
1276 self.writer,
1277 " xmlns:{}=\"{}\"",
1278 escape_element_name(&prefix),
1279 escape_attribute_value(&uri, self.preserve_entities)
1280 )
1281 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1282 }
1283 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1284 return Ok(());
1285 }
1286
1287 write!(self.writer, "<{}", escape_element_name(element_name))
1288 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1289 if let Some((prefix, uri)) = xmlns_decl {
1290 write!(
1291 self.writer,
1292 " xmlns:{}=\"{}\"",
1293 escape_element_name(&prefix),
1294 escape_attribute_value(&uri, self.preserve_entities)
1295 )
1296 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1297 }
1298 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1299
1300 for (i, (_, field_peek)) in fields.into_iter().enumerate() {
1301 let field_name = format!("_{i}");
1302 self.serialize_element(&field_name, field_peek)?;
1303 }
1304
1305 write!(self.writer, "</{}>", escape_element_name(element_name))
1306 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1307 return Ok(());
1308 }
1309 StructKind::Struct => {
1310 }
1312 }
1313
1314 let ns_all = shape.xml_ns_all();
1316
1317 let effective_default_ns: Option<&str> = parent_default_ns;
1322
1323 struct AttrInfo<'a> {
1325 name: &'a str,
1326 value: String,
1327 namespace: Option<&'static str>,
1328 }
1329 let mut attributes: Vec<AttrInfo> = Vec::new();
1330 let mut elements: Vec<(facet_reflect::FieldItem, Peek<'mem, 'facet>)> = Vec::new();
1331 let mut elements_list: Vec<Peek<'mem, 'facet>> = Vec::new();
1332 let mut text_content: Option<Peek<'mem, 'facet>> = None;
1333
1334 for (field_item, field_peek) in struct_peek.fields_for_serialize() {
1335 let field = &field_item.field;
1336
1337 if field.is_xml_attribute() {
1338 let value = if field.proxy_convert_out_fn().is_some() {
1339 if let Ok(owned) = field_peek.custom_serialization(*field) {
1340 value_to_string(owned.as_peek(), self.float_formatter)
1341 } else {
1342 value_to_string(field_peek, self.float_formatter)
1343 }
1344 } else {
1345 value_to_string(field_peek, self.float_formatter)
1346 };
1347 if let Some(value) = value {
1348 let namespace = Self::get_field_namespace(field, ns_all, true);
1350 attributes.push(AttrInfo {
1351 name: field_item.name,
1352 value,
1353 namespace,
1354 });
1355 }
1356 } else if field.is_xml_element() {
1357 elements.push((field_item, field_peek));
1358 } else if field.is_xml_elements() {
1359 elements_list.push(field_peek);
1360 } else if field.is_xml_text() {
1361 text_content = Some(field_peek);
1362 }
1363 }
1364
1365 let has_content =
1366 !elements.is_empty() || !elements_list.is_empty() || text_content.is_some();
1367
1368 let mut xmlns_decls: Vec<(String, String)> = Vec::new();
1371 let mut attr_prefixes: Vec<Option<String>> = Vec::new();
1372
1373 if let Some((prefix, uri)) = xmlns_decl {
1375 xmlns_decls.push((prefix, uri));
1376 }
1377
1378 for attr in &attributes {
1379 if let Some(ns_uri) = attr.namespace {
1380 let prefix = self.get_or_create_prefix(ns_uri);
1381 if !xmlns_decls.iter().any(|(_, u)| u == ns_uri) {
1383 xmlns_decls.push((prefix.clone(), ns_uri.to_string()));
1384 }
1385 attr_prefixes.push(Some(prefix));
1386 } else {
1387 attr_prefixes.push(None);
1388 }
1389 }
1390
1391 write!(self.writer, "<{}", escape_element_name(element_name))
1393 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1394
1395 for (prefix, uri) in &xmlns_decls {
1402 write!(
1403 self.writer,
1404 " xmlns:{}=\"{}\"",
1405 escape_element_name(prefix),
1406 escape_attribute_value(uri, self.preserve_entities)
1407 )
1408 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1409 }
1410
1411 for (attr, prefix) in attributes.iter().zip(attr_prefixes.iter()) {
1413 let attr_name = if let Some(p) = prefix {
1414 format!("{p}:{}", attr.name)
1415 } else {
1416 attr.name.to_string()
1417 };
1418 write!(
1419 self.writer,
1420 " {}=\"{}\"",
1421 escape_element_name(&attr_name),
1422 escape_attribute_value(&attr.value, self.preserve_entities)
1423 )
1424 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1425 }
1426
1427 if !has_content {
1428 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1429 return Ok(());
1430 }
1431
1432 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1433
1434 if let Some(text_peek) = text_content {
1435 self.serialize_text_value(text_peek)?;
1436 }
1437
1438 let has_child_elements = !elements.is_empty() || !elements_list.is_empty();
1440
1441 if has_child_elements {
1442 self.depth += 1;
1443 }
1444
1445 for (field_item, field_peek) in elements {
1446 let field_ns = Self::get_field_namespace(&field_item.field, ns_all, false);
1448
1449 self.write_newline()?;
1450 self.write_indent()?;
1451
1452 if field_item.field.proxy_convert_out_fn().is_some() {
1453 if let Ok(owned) = field_peek.custom_serialization(field_item.field) {
1454 self.serialize_namespaced_element(
1455 field_item.name,
1456 owned.as_peek(),
1457 field_ns,
1458 effective_default_ns,
1459 )?;
1460 } else {
1461 self.serialize_namespaced_element(
1462 field_item.name,
1463 field_peek,
1464 field_ns,
1465 effective_default_ns,
1466 )?;
1467 }
1468 } else {
1469 self.serialize_namespaced_element(
1470 field_item.name,
1471 field_peek,
1472 field_ns,
1473 effective_default_ns,
1474 )?;
1475 }
1476 }
1477
1478 for field_peek in elements_list {
1479 self.serialize_elements_list(field_peek)?;
1480 }
1481
1482 if has_child_elements {
1483 self.depth -= 1;
1484 self.write_newline()?;
1485 self.write_indent()?;
1486 }
1487
1488 write!(self.writer, "</{}>", escape_element_name(element_name))
1489 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1490
1491 Ok(())
1492 }
1493
1494 fn serialize_enum_as_namespaced_element<'mem, 'facet>(
1496 &mut self,
1497 prefixed_element_name: &str,
1498 enum_peek: facet_reflect::PeekEnum<'mem, 'facet>,
1499 xmlns_decl: Option<(String, String)>,
1500 ) -> Result<()> {
1501 let shape = enum_peek.shape();
1502 let variant_name = enum_peek
1503 .variant_name_active()
1504 .map_err(|_| XmlErrorKind::SerializeUnknownElementType)?;
1505
1506 let fields: Vec<_> = enum_peek.fields_for_serialize().collect();
1507
1508 let is_untagged = shape.is_untagged();
1509 let tag_attr = shape.get_tag_attr();
1510 let content_attr = shape.get_content_attr();
1511
1512 let write_open_tag =
1514 |writer: &mut W, name: &str, xmlns: &Option<(String, String)>| -> Result<()> {
1515 write!(writer, "<{}", escape_element_name(name))
1516 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1517 if let Some((prefix, uri)) = xmlns {
1518 write!(
1519 writer,
1520 " xmlns:{}=\"{}\"",
1521 escape_element_name(prefix),
1522 escape_attribute_value(uri, self.preserve_entities)
1523 )
1524 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1525 }
1526 Ok(())
1527 };
1528
1529 if is_untagged {
1530 if fields.is_empty() {
1532 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1533 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1534 } else if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
1535 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1537 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1538 self.serialize_value(fields[0].1)?;
1539 write!(
1540 self.writer,
1541 "</{}>",
1542 escape_element_name(prefixed_element_name)
1543 )
1544 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1545 } else {
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 for (field_item, field_peek) in fields {
1549 self.serialize_element(field_item.name, field_peek)?;
1550 }
1551 write!(
1552 self.writer,
1553 "</{}>",
1554 escape_element_name(prefixed_element_name)
1555 )
1556 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1557 }
1558 } else if let Some(tag) = tag_attr {
1559 if let Some(content) = content_attr {
1560 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1562 write!(
1563 self.writer,
1564 " {}=\"{}\">",
1565 escape_element_name(tag),
1566 escape_attribute_value(variant_name, self.preserve_entities)
1567 )
1568 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1569
1570 if !fields.is_empty() {
1571 write!(self.writer, "<{}>", escape_element_name(content))
1572 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1573 self.serialize_variant_fields(&fields)?;
1574 write!(self.writer, "</{}>", escape_element_name(content))
1575 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1576 }
1577
1578 write!(
1579 self.writer,
1580 "</{}>",
1581 escape_element_name(prefixed_element_name)
1582 )
1583 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1584 } else {
1585 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1587 write!(
1588 self.writer,
1589 " {}=\"{}\">",
1590 escape_element_name(tag),
1591 escape_attribute_value(variant_name, self.preserve_entities)
1592 )
1593 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1594 self.serialize_variant_fields(&fields)?;
1595 write!(
1596 self.writer,
1597 "</{}>",
1598 escape_element_name(prefixed_element_name)
1599 )
1600 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1601 }
1602 } else {
1603 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1605 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1606
1607 if fields.is_empty() {
1608 write!(self.writer, "<{}/>", escape_element_name(variant_name))
1609 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1610 } else if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
1611 self.serialize_element(variant_name, fields[0].1)?;
1612 } else {
1613 write!(self.writer, "<{}>", escape_element_name(variant_name))
1614 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1615 for (field_item, field_peek) in fields {
1616 self.serialize_element(field_item.name, field_peek)?;
1617 }
1618 write!(self.writer, "</{}>", escape_element_name(variant_name))
1619 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1620 }
1621
1622 write!(
1623 self.writer,
1624 "</{}>",
1625 escape_element_name(prefixed_element_name)
1626 )
1627 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1628 }
1629
1630 Ok(())
1631 }
1632
1633 fn serialize_elements_list<'mem, 'facet>(&mut self, peek: Peek<'mem, 'facet>) -> Result<()> {
1634 let list_peek = peek
1635 .into_list()
1636 .map_err(|_| XmlErrorKind::SerializeNotList)?;
1637
1638 for item_peek in list_peek.iter() {
1639 self.write_newline()?;
1640 self.write_indent()?;
1641 self.serialize_list_item_element(item_peek)?;
1642 }
1643
1644 Ok(())
1645 }
1646
1647 fn serialize_list_item_element<'mem, 'facet>(
1648 &mut self,
1649 peek: Peek<'mem, 'facet>,
1650 ) -> Result<()> {
1651 if let Ok(enum_peek) = peek.into_enum() {
1653 let variant_name = enum_peek
1654 .variant_name_active()
1655 .map_err(|_| XmlErrorKind::SerializeUnknownElementType)?;
1656
1657 let fields: Vec<_> = enum_peek.fields_for_serialize().collect();
1659
1660 if fields.is_empty() {
1661 write!(self.writer, "<{}/>", escape_element_name(variant_name))
1663 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1664 } else if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
1665 self.serialize_element(variant_name, fields[0].1)?;
1667 } else {
1668 write!(self.writer, "<{}>", escape_element_name(variant_name))
1670 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1671
1672 for (field_item, field_peek) in fields {
1673 self.serialize_element(field_item.name, field_peek)?;
1674 }
1675
1676 write!(self.writer, "</{}>", escape_element_name(variant_name))
1677 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1678 }
1679 return Ok(());
1680 }
1681
1682 let type_name = peek.shape().type_identifier;
1684 self.serialize_element(type_name, peek)
1685 }
1686
1687 fn serialize_text_value<'mem, 'facet>(&mut self, peek: Peek<'mem, 'facet>) -> Result<()> {
1688 if let Ok(opt_peek) = peek.into_option() {
1690 if opt_peek.is_none() {
1691 return Ok(());
1692 }
1693 if let Some(inner) = opt_peek.value() {
1694 return self.serialize_text_value(inner);
1695 }
1696 return Ok(());
1697 }
1698
1699 if is_spanned_shape(peek.shape())
1701 && let Ok(struct_peek) = peek.into_struct()
1702 && let Ok(value_peek) = struct_peek.field_by_name("value")
1703 {
1704 return self.serialize_text_value(value_peek);
1705 }
1706
1707 self.serialize_value(peek)
1708 }
1709
1710 fn serialize_value<'mem, 'facet>(&mut self, peek: Peek<'mem, 'facet>) -> Result<()> {
1711 if let Ok(opt_peek) = peek.into_option() {
1713 if opt_peek.is_none() {
1714 return Ok(());
1715 }
1716 if let Some(inner) = opt_peek.value() {
1717 return self.serialize_value(inner);
1718 }
1719 return Ok(());
1720 }
1721
1722 if is_spanned_shape(peek.shape())
1724 && let Ok(struct_peek) = peek.into_struct()
1725 && let Ok(value_peek) = struct_peek.field_by_name("value")
1726 {
1727 return self.serialize_value(value_peek);
1728 }
1729
1730 let peek = peek.innermost_peek();
1732
1733 if let Some(s) = peek.as_str() {
1735 write!(self.writer, "{}", escape_text(s, self.preserve_entities))
1736 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1737 return Ok(());
1738 }
1739
1740 if let Ok(v) = peek.get::<bool>() {
1742 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1743 return Ok(());
1744 }
1745
1746 if let Ok(v) = peek.get::<i8>() {
1747 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1748 return Ok(());
1749 }
1750 if let Ok(v) = peek.get::<i16>() {
1751 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1752 return Ok(());
1753 }
1754 if let Ok(v) = peek.get::<i32>() {
1755 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1756 return Ok(());
1757 }
1758 if let Ok(v) = peek.get::<i64>() {
1759 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1760 return Ok(());
1761 }
1762
1763 if let Ok(v) = peek.get::<u8>() {
1764 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1765 return Ok(());
1766 }
1767 if let Ok(v) = peek.get::<u16>() {
1768 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1769 return Ok(());
1770 }
1771 if let Ok(v) = peek.get::<u32>() {
1772 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1773 return Ok(());
1774 }
1775 if let Ok(v) = peek.get::<u64>() {
1776 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1777 return Ok(());
1778 }
1779
1780 if let Ok(v) = peek.get::<f32>() {
1781 if let Some(fmt) = self.float_formatter {
1782 fmt(f64::from(*v), &mut self.writer)
1783 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1784 } else {
1785 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1786 }
1787 return Ok(());
1788 }
1789 if let Ok(v) = peek.get::<f64>() {
1790 if let Some(fmt) = self.float_formatter {
1791 fmt(*v, &mut self.writer).map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1792 } else {
1793 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1794 }
1795 return Ok(());
1796 }
1797
1798 if let Ok(v) = peek.get::<char>() {
1799 write!(
1800 self.writer,
1801 "{}",
1802 escape_text(&v.to_string(), self.preserve_entities)
1803 )
1804 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1805 return Ok(());
1806 }
1807
1808 Err(XmlErrorKind::SerializeUnknownValueType.into())
1809 }
1810}
1811
1812fn value_to_string<'mem, 'facet>(
1814 peek: Peek<'mem, 'facet>,
1815 float_formatter: Option<FloatFormatter>,
1816) -> Option<String> {
1817 if let Ok(opt_peek) = peek.into_option() {
1819 if opt_peek.is_none() {
1820 return None;
1821 }
1822 if let Some(inner) = opt_peek.value() {
1823 return value_to_string(inner, float_formatter);
1824 }
1825 return None;
1826 }
1827
1828 if is_spanned_shape(peek.shape())
1830 && let Ok(struct_peek) = peek.into_struct()
1831 && let Ok(value_peek) = struct_peek.field_by_name("value")
1832 {
1833 return value_to_string(value_peek, float_formatter);
1834 }
1835
1836 let peek = peek.innermost_peek();
1838
1839 if let Some(s) = peek.as_str() {
1841 return Some(s.to_string());
1842 }
1843
1844 if let Ok(v) = peek.get::<bool>() {
1846 return Some(v.to_string());
1847 }
1848
1849 if let Ok(v) = peek.get::<i8>() {
1850 return Some(v.to_string());
1851 }
1852 if let Ok(v) = peek.get::<i16>() {
1853 return Some(v.to_string());
1854 }
1855 if let Ok(v) = peek.get::<i32>() {
1856 return Some(v.to_string());
1857 }
1858 if let Ok(v) = peek.get::<i64>() {
1859 return Some(v.to_string());
1860 }
1861
1862 if let Ok(v) = peek.get::<u8>() {
1863 return Some(v.to_string());
1864 }
1865 if let Ok(v) = peek.get::<u16>() {
1866 return Some(v.to_string());
1867 }
1868 if let Ok(v) = peek.get::<u32>() {
1869 return Some(v.to_string());
1870 }
1871 if let Ok(v) = peek.get::<u64>() {
1872 return Some(v.to_string());
1873 }
1874
1875 if let Ok(v) = peek.get::<f32>() {
1876 if let Some(fmt) = float_formatter {
1877 let mut buf = Vec::new();
1878 if fmt(f64::from(*v), &mut buf).is_ok() {
1879 return String::from_utf8(buf).ok();
1880 }
1881 }
1882 return Some(v.to_string());
1883 }
1884 if let Ok(v) = peek.get::<f64>() {
1885 if let Some(fmt) = float_formatter {
1886 let mut buf = Vec::new();
1887 if fmt(*v, &mut buf).is_ok() {
1888 return String::from_utf8(buf).ok();
1889 }
1890 }
1891 return Some(v.to_string());
1892 }
1893
1894 if let Ok(v) = peek.get::<char>() {
1895 return Some(v.to_string());
1896 }
1897
1898 None
1899}
1900
1901fn escape_text(s: &str, preserve_entities: bool) -> String {
1903 if preserve_entities {
1904 escape_preserving_entities(s, false)
1905 } else {
1906 let mut result = String::with_capacity(s.len());
1907 for c in s.chars() {
1908 match c {
1909 '<' => result.push_str("<"),
1910 '>' => result.push_str(">"),
1911 '&' => result.push_str("&"),
1912 _ => result.push(c),
1913 }
1914 }
1915 result
1916 }
1917}
1918
1919fn escape_attribute_value(s: &str, preserve_entities: bool) -> String {
1921 if preserve_entities {
1922 escape_preserving_entities(s, true)
1923 } else {
1924 let mut result = String::with_capacity(s.len());
1925 for c in s.chars() {
1926 match c {
1927 '<' => result.push_str("<"),
1928 '>' => result.push_str(">"),
1929 '&' => result.push_str("&"),
1930 '"' => result.push_str("""),
1931 '\'' => result.push_str("'"),
1932 _ => result.push(c),
1933 }
1934 }
1935 result
1936 }
1937}
1938
1939fn escape_preserving_entities(s: &str, is_attribute: bool) -> String {
1946 let mut result = String::with_capacity(s.len());
1947 let chars: Vec<char> = s.chars().collect();
1948 let mut i = 0;
1949
1950 while i < chars.len() {
1951 let c = chars[i];
1952 match c {
1953 '<' => result.push_str("<"),
1954 '>' => result.push_str(">"),
1955 '"' if is_attribute => result.push_str("""),
1956 '\'' if is_attribute => result.push_str("'"),
1957 '&' => {
1958 if let Some(entity_len) = try_parse_entity_reference(&chars[i..]) {
1960 for j in 0..entity_len {
1962 result.push(chars[i + j]);
1963 }
1964 i += entity_len;
1965 continue;
1966 } else {
1967 result.push_str("&");
1969 }
1970 }
1971 _ => result.push(c),
1972 }
1973 i += 1;
1974 }
1975
1976 result
1977}
1978
1979fn try_parse_entity_reference(chars: &[char]) -> Option<usize> {
1987 if chars.is_empty() || chars[0] != '&' {
1988 return None;
1989 }
1990
1991 if chars.len() < 3 {
1993 return None;
1994 }
1995
1996 let mut len = 1; if chars[1] == '#' {
1999 len = 2;
2001
2002 if len < chars.len() && (chars[len] == 'x' || chars[len] == 'X') {
2003 len += 1;
2005 let start = len;
2006 while len < chars.len() && chars[len].is_ascii_hexdigit() {
2007 len += 1;
2008 }
2009 if len == start {
2011 return None;
2012 }
2013 } else {
2014 let start = len;
2016 while len < chars.len() && chars[len].is_ascii_digit() {
2017 len += 1;
2018 }
2019 if len == start {
2021 return None;
2022 }
2023 }
2024 } else {
2025 if !chars[len].is_ascii_alphabetic() && chars[len] != '_' {
2028 return None;
2029 }
2030 len += 1;
2031 while len < chars.len()
2032 && (chars[len].is_ascii_alphanumeric()
2033 || chars[len] == '_'
2034 || chars[len] == '-'
2035 || chars[len] == '.')
2036 {
2037 len += 1;
2038 }
2039 }
2040
2041 if len >= chars.len() || chars[len] != ';' {
2043 return None;
2044 }
2045
2046 Some(len + 1) }
2048
2049fn escape_element_name(name: &str) -> &str {
2051 name
2052}