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}
33
34impl Default for SerializeOptions {
35 fn default() -> Self {
36 Self {
37 pretty: false,
38 indent: " ",
39 float_formatter: None,
40 }
41 }
42}
43
44impl std::fmt::Debug for SerializeOptions {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 f.debug_struct("SerializeOptions")
47 .field("pretty", &self.pretty)
48 .field("indent", &self.indent)
49 .field("float_formatter", &self.float_formatter.map(|_| "..."))
50 .finish()
51 }
52}
53
54impl SerializeOptions {
55 pub fn new() -> Self {
57 Self::default()
58 }
59
60 pub fn pretty(mut self) -> Self {
62 self.pretty = true;
63 self
64 }
65
66 pub fn indent(mut self, indent: &'static str) -> Self {
68 self.indent = indent;
69 self.pretty = true;
70 self
71 }
72
73 fn indent_str(&self) -> Option<&str> {
75 if self.pretty { Some(self.indent) } else { None }
76 }
77
78 pub fn float_formatter(mut self, formatter: FloatFormatter) -> Self {
111 self.float_formatter = Some(formatter);
112 self
113 }
114}
115
116const WELL_KNOWN_NAMESPACES: &[(&str, &str)] = &[
118 ("http://www.w3.org/2001/XMLSchema-instance", "xsi"),
119 ("http://www.w3.org/2001/XMLSchema", "xs"),
120 ("http://www.w3.org/XML/1998/namespace", "xml"),
121 ("http://www.w3.org/1999/xlink", "xlink"),
122 ("http://www.w3.org/2000/svg", "svg"),
123 ("http://www.w3.org/1999/xhtml", "xhtml"),
124 ("http://schemas.xmlsoap.org/soap/envelope/", "soap"),
125 ("http://www.w3.org/2003/05/soap-envelope", "soap12"),
126 ("http://schemas.android.com/apk/res/android", "android"),
127];
128
129pub(crate) type Result<T> = std::result::Result<T, XmlError>;
130
131pub fn to_string<T: Facet<'static>>(value: &T) -> Result<String> {
157 to_string_with_options(value, &SerializeOptions::default())
158}
159
160pub fn to_string_pretty<T: Facet<'static>>(value: &T) -> Result<String> {
185 to_string_with_options(value, &SerializeOptions::default().pretty())
186}
187
188pub fn to_string_with_options<T: Facet<'static>>(
217 value: &T,
218 options: &SerializeOptions,
219) -> Result<String> {
220 let mut output = Vec::new();
221 to_writer_with_options(&mut output, value, options)?;
222 Ok(String::from_utf8(output).expect("XML output should be valid UTF-8"))
223}
224
225pub fn to_writer<W: Write, T: Facet<'static>>(writer: &mut W, value: &T) -> Result<()> {
255 to_writer_with_options(writer, value, &SerializeOptions::default())
256}
257
258pub fn to_writer_pretty<W: Write, T: Facet<'static>>(writer: &mut W, value: &T) -> Result<()> {
285 to_writer_with_options(writer, value, &SerializeOptions::default().pretty())
286}
287
288pub fn to_writer_with_options<W: Write, T: Facet<'static>>(
323 writer: &mut W,
324 value: &T,
325 options: &SerializeOptions,
326) -> Result<()> {
327 let peek = Peek::new(value);
328 let mut serializer = XmlSerializer::new(writer, options.indent_str(), options.float_formatter);
329
330 let type_name = crate::deserialize::get_shape_display_name(peek.shape());
332 serializer.serialize_element(type_name, peek)
333}
334
335struct XmlSerializer<'a, W> {
336 writer: W,
337 declared_namespaces: HashMap<String, String>,
339 next_ns_index: usize,
341 indent: Option<&'a str>,
343 depth: usize,
345 current_default_ns: Option<String>,
348 float_formatter: Option<FloatFormatter>,
350}
351
352impl<'a, W: Write> XmlSerializer<'a, W> {
353 fn new(writer: W, indent: Option<&'a str>, float_formatter: Option<FloatFormatter>) -> Self {
354 Self {
355 writer,
356 declared_namespaces: HashMap::new(),
357 next_ns_index: 0,
358 indent,
359 depth: 0,
360 current_default_ns: None,
361 float_formatter,
362 }
363 }
364
365 fn write_indent(&mut self) -> Result<()> {
367 if let Some(indent_str) = self.indent {
368 for _ in 0..self.depth {
369 self.writer
370 .write_all(indent_str.as_bytes())
371 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
372 }
373 }
374 Ok(())
375 }
376
377 fn write_newline(&mut self) -> Result<()> {
379 if self.indent.is_some() {
380 self.writer
381 .write_all(b"\n")
382 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
383 }
384 Ok(())
385 }
386
387 fn get_or_create_prefix(&mut self, namespace_uri: &str) -> String {
394 if let Some(prefix) = self.declared_namespaces.get(namespace_uri) {
396 return prefix.clone();
397 }
398
399 let prefix = WELL_KNOWN_NAMESPACES
401 .iter()
402 .find(|(uri, _)| *uri == namespace_uri)
403 .map(|(_, prefix)| (*prefix).to_string())
404 .unwrap_or_else(|| {
405 let prefix = format!("ns{}", self.next_ns_index);
407 self.next_ns_index += 1;
408 prefix
409 });
410
411 let final_prefix = if self.declared_namespaces.values().any(|p| p == &prefix) {
413 let prefix = format!("ns{}", self.next_ns_index);
415 self.next_ns_index += 1;
416 prefix
417 } else {
418 prefix
419 };
420
421 self.declared_namespaces
422 .insert(namespace_uri.to_string(), final_prefix.clone());
423 final_prefix
424 }
425
426 fn get_field_namespace(
435 field: &Field,
436 ns_all: Option<&'static str>,
437 is_attribute: bool,
438 ) -> Option<&'static str> {
439 if is_attribute {
440 field.xml_ns()
443 } else {
444 field.xml_ns().or(ns_all)
446 }
447 }
448
449 fn serialize_element<'mem, 'facet>(
450 &mut self,
451 element_name: &str,
452 peek: Peek<'mem, 'facet>,
453 ) -> Result<()> {
454 if let Ok(opt_peek) = peek.into_option() {
456 if opt_peek.is_none() {
457 return Ok(());
458 }
459 if let Some(inner) = opt_peek.value() {
460 return self.serialize_element(element_name, inner);
461 }
462 return Ok(());
463 }
464
465 if is_spanned_shape(peek.shape())
467 && let Ok(struct_peek) = peek.into_struct()
468 && let Ok(value_field) = struct_peek.field_by_name("value")
469 {
470 return self.serialize_element(element_name, value_field);
471 }
472
473 let shape = peek.shape();
475 if let Ok(struct_peek) = peek.into_struct() {
476 return self.serialize_struct_as_element(element_name, struct_peek, shape);
477 }
478
479 if let Ok(enum_peek) = peek.into_enum() {
481 return self.serialize_enum_as_element(element_name, enum_peek);
482 }
483
484 if self.try_serialize_bytes_as_element(element_name, peek)? {
486 return Ok(());
487 }
488
489 if let Ok(list_peek) = peek.into_list_like() {
491 return self.serialize_list_as_element(element_name, list_peek);
492 }
493
494 if let Ok(map_peek) = peek.into_map() {
496 return self.serialize_map_as_element(element_name, map_peek);
497 }
498
499 write!(self.writer, "<{}>", escape_element_name(element_name))
501 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
502 self.serialize_value(peek)?;
503 write!(self.writer, "</{}>", escape_element_name(element_name))
504 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
505
506 Ok(())
507 }
508
509 fn serialize_enum_as_element<'mem, 'facet>(
510 &mut self,
511 element_name: &str,
512 enum_peek: facet_reflect::PeekEnum<'mem, 'facet>,
513 ) -> Result<()> {
514 let shape = enum_peek.shape();
515 let variant_name = enum_peek
516 .variant_name_active()
517 .map_err(|_| XmlErrorKind::SerializeUnknownElementType)?;
518
519 let fields: Vec<_> = enum_peek.fields_for_serialize().collect();
520
521 let is_untagged = shape.is_untagged();
523 let tag_attr = shape.get_tag_attr();
524 let content_attr = shape.get_content_attr();
525
526 if is_untagged {
527 self.serialize_enum_content(element_name, variant_name, &fields)?;
529 } else if let Some(tag) = tag_attr {
530 if let Some(content) = content_attr {
531 write!(
533 self.writer,
534 "<{} {}=\"{}\">",
535 escape_element_name(element_name),
536 escape_element_name(tag),
537 escape_attribute_value(variant_name)
538 )
539 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
540
541 if !fields.is_empty() {
542 write!(self.writer, "<{}>", escape_element_name(content))
544 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
545 self.serialize_variant_fields(&fields)?;
546 write!(self.writer, "</{}>", escape_element_name(content))
547 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
548 }
549
550 write!(self.writer, "</{}>", escape_element_name(element_name))
551 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
552 } else {
553 write!(
555 self.writer,
556 "<{} {}=\"{}\">",
557 escape_element_name(element_name),
558 escape_element_name(tag),
559 escape_attribute_value(variant_name)
560 )
561 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
562
563 self.serialize_variant_fields(&fields)?;
565
566 write!(self.writer, "</{}>", escape_element_name(element_name))
567 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
568 }
569 } else {
570 write!(self.writer, "<{}>", escape_element_name(element_name))
572 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
573
574 if fields.is_empty() {
575 write!(self.writer, "<{}/>", escape_element_name(variant_name))
577 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
578 } else if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
579 self.serialize_element(variant_name, fields[0].1)?;
581 } else {
582 write!(self.writer, "<{}>", escape_element_name(variant_name))
584 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
585
586 for (field_item, field_peek) in fields {
587 self.serialize_element(field_item.name, field_peek)?;
588 }
589
590 write!(self.writer, "</{}>", escape_element_name(variant_name))
591 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
592 }
593
594 write!(self.writer, "</{}>", escape_element_name(element_name))
595 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
596 }
597
598 Ok(())
599 }
600
601 fn serialize_enum_content<'mem, 'facet>(
603 &mut self,
604 element_name: &str,
605 variant_name: &str,
606 fields: &[(facet_reflect::FieldItem, Peek<'mem, 'facet>)],
607 ) -> Result<()> {
608 if fields.is_empty() {
609 write!(self.writer, "<{}/>", escape_element_name(element_name))
611 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
612 } else if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
613 self.serialize_element(element_name, fields[0].1)?;
615 } else {
616 write!(self.writer, "<{}>", escape_element_name(element_name))
618 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
619
620 for (field_item, field_peek) in fields {
621 let _ = variant_name; self.serialize_element(field_item.name, *field_peek)?;
624 }
625
626 write!(self.writer, "</{}>", escape_element_name(element_name))
627 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
628 }
629 Ok(())
630 }
631
632 fn serialize_variant_fields<'mem, 'facet>(
634 &mut self,
635 fields: &[(facet_reflect::FieldItem, Peek<'mem, 'facet>)],
636 ) -> Result<()> {
637 if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
638 self.serialize_value(fields[0].1)?;
640 } else {
641 for (field_item, field_peek) in fields {
642 self.serialize_element(field_item.name, *field_peek)?;
643 }
644 }
645 Ok(())
646 }
647
648 fn serialize_list_as_element<'mem, 'facet>(
649 &mut self,
650 element_name: &str,
651 list_peek: facet_reflect::PeekListLike<'mem, 'facet>,
652 ) -> Result<()> {
653 write!(self.writer, "<{}>", escape_element_name(element_name))
654 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
655
656 let has_items = list_peek.iter().next().is_some();
657 if has_items {
658 self.depth += 1;
659 }
660
661 for item in list_peek.iter() {
662 self.write_newline()?;
663 self.write_indent()?;
664 self.serialize_list_item_element(item)?;
665 }
666
667 if has_items {
668 self.depth -= 1;
669 self.write_newline()?;
670 self.write_indent()?;
671 }
672
673 write!(self.writer, "</{}>", escape_element_name(element_name))
674 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
675
676 Ok(())
677 }
678
679 fn serialize_map_as_element<'mem, 'facet>(
680 &mut self,
681 element_name: &str,
682 map_peek: facet_reflect::PeekMap<'mem, 'facet>,
683 ) -> Result<()> {
684 write!(self.writer, "<{}>", escape_element_name(element_name))
685 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
686
687 let has_items = map_peek.iter().next().is_some();
688 if has_items {
689 self.depth += 1;
690 }
691
692 for (key, value) in map_peek.iter() {
693 self.write_newline()?;
694 self.write_indent()?;
695 if let Some(key_str) = key.as_str() {
697 self.serialize_element(key_str, value)?;
698 } else if let Some(key_val) = value_to_string(key, self.float_formatter) {
699 self.serialize_element(&key_val, value)?;
700 } else {
701 write!(self.writer, "<entry>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
703 self.serialize_value(key)?;
704 self.serialize_value(value)?;
705 write!(self.writer, "</entry>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
706 }
707 }
708
709 if has_items {
710 self.depth -= 1;
711 self.write_newline()?;
712 self.write_indent()?;
713 }
714
715 write!(self.writer, "</{}>", escape_element_name(element_name))
716 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
717
718 Ok(())
719 }
720
721 fn try_serialize_bytes_as_element<'mem, 'facet>(
724 &mut self,
725 element_name: &str,
726 peek: Peek<'mem, 'facet>,
727 ) -> Result<bool> {
728 let shape = peek.shape();
729
730 if let Def::List(ld) = &shape.def
732 && ld.t().is_type::<u8>()
733 && let Some(bytes) = peek.as_bytes()
734 {
735 let encoded = BASE64_STANDARD.encode(bytes);
736 write!(self.writer, "<{}>", escape_element_name(element_name))
737 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
738 write!(self.writer, "{}", escape_text(&encoded))
739 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
740 write!(self.writer, "</{}>", escape_element_name(element_name))
741 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
742 return Ok(true);
743 }
744
745 if let Def::Array(ad) = &shape.def
747 && ad.t().is_type::<u8>()
748 {
749 if let Ok(list_peek) = peek.into_list_like() {
751 let bytes: Vec<u8> = list_peek
752 .iter()
753 .filter_map(|p| p.get::<u8>().ok().copied())
754 .collect();
755 let encoded = BASE64_STANDARD.encode(&bytes);
756 write!(self.writer, "<{}>", escape_element_name(element_name))
757 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
758 write!(self.writer, "{}", escape_text(&encoded))
759 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
760 write!(self.writer, "</{}>", escape_element_name(element_name))
761 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
762 return Ok(true);
763 }
764 }
765
766 if let Def::Slice(sd) = &shape.def
768 && sd.t().is_type::<u8>()
769 && let Some(bytes) = peek.as_bytes()
770 {
771 let encoded = BASE64_STANDARD.encode(bytes);
772 write!(self.writer, "<{}>", escape_element_name(element_name))
773 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
774 write!(self.writer, "{}", escape_text(&encoded))
775 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
776 write!(self.writer, "</{}>", escape_element_name(element_name))
777 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
778 return Ok(true);
779 }
780
781 Ok(false)
782 }
783
784 fn serialize_struct_as_element<'mem, 'facet>(
785 &mut self,
786 element_name: &str,
787 struct_peek: facet_reflect::PeekStruct<'mem, 'facet>,
788 shape: &'static Shape,
789 ) -> Result<()> {
790 let struct_ty = struct_peek.ty();
791
792 match struct_ty.kind {
793 StructKind::Unit => {
794 write!(self.writer, "<{}/>", escape_element_name(element_name))
796 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
797 return Ok(());
798 }
799 StructKind::Tuple | StructKind::TupleStruct => {
800 let fields: Vec<_> = struct_peek.fields_for_serialize().collect();
802 if fields.is_empty() {
803 write!(self.writer, "<{}/>", escape_element_name(element_name))
804 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
805 return Ok(());
806 }
807
808 write!(self.writer, "<{}>", escape_element_name(element_name))
809 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
810
811 for (i, (_, field_peek)) in fields.into_iter().enumerate() {
812 let field_name = format!("_{i}");
814 self.serialize_element(&field_name, field_peek)?;
815 }
816
817 write!(self.writer, "</{}>", escape_element_name(element_name))
818 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
819 return Ok(());
820 }
821 StructKind::Struct => {
822 }
824 }
825
826 let fields = struct_ty.fields;
827 let missing = fields_missing_xml_annotations(fields, XmlAnnotationPhase::Serialize);
828 if !missing.is_empty() {
829 let field_info = missing
830 .into_iter()
831 .map(|field| (field.name, field.shape().type_identifier))
832 .collect();
833 return Err(XmlError::new(XmlErrorKind::MissingXmlAnnotations {
834 type_name: shape.type_identifier,
835 phase: MissingAnnotationPhase::Serialize,
836 fields: field_info,
837 }));
838 }
839
840 let ns_all = shape.xml_ns_all();
842
843 struct AttrInfo<'a> {
845 name: &'a str,
846 value: String,
847 namespace: Option<&'static str>,
848 }
849 let mut attributes: Vec<AttrInfo> = Vec::new();
850 let mut elements: Vec<(facet_reflect::FieldItem, Peek<'mem, 'facet>)> = Vec::new();
851 let mut elements_list: Vec<Peek<'mem, 'facet>> = Vec::new();
852 let mut text_content: Option<Peek<'mem, 'facet>> = None;
853
854 for (field_item, field_peek) in struct_peek.fields_for_serialize() {
855 let field = &field_item.field;
856
857 if field.is_xml_attribute() {
859 let value = if field.proxy_convert_out_fn().is_some() {
860 if let Ok(owned) = field_peek.custom_serialization(*field) {
862 value_to_string(owned.as_peek(), self.float_formatter)
863 } else {
864 value_to_string(field_peek, self.float_formatter)
865 }
866 } else {
867 value_to_string(field_peek, self.float_formatter)
868 };
869 if let Some(value) = value {
870 let namespace = Self::get_field_namespace(field, ns_all, true);
872 attributes.push(AttrInfo {
873 name: field_item.name,
874 value,
875 namespace,
876 });
877 }
878 } else if field.is_xml_element() {
879 elements.push((field_item, field_peek));
880 } else if field.is_xml_elements() {
881 elements_list.push(field_peek);
882 } else if field.is_xml_text() {
883 text_content = Some(field_peek);
884 }
885 }
886
887 let has_content =
889 !elements.is_empty() || !elements_list.is_empty() || text_content.is_some();
890
891 let mut xmlns_decls: Vec<(String, String)> = Vec::new(); let mut attr_prefixes: Vec<Option<String>> = Vec::new(); for attr in &attributes {
898 if let Some(ns_uri) = attr.namespace {
899 let prefix = self.get_or_create_prefix(ns_uri);
900 if !xmlns_decls.iter().any(|(_, u)| u == ns_uri) {
902 xmlns_decls.push((prefix.clone(), ns_uri.to_string()));
903 }
904 attr_prefixes.push(Some(prefix));
905 } else {
906 attr_prefixes.push(None);
907 }
908 }
909
910 write!(self.writer, "<{}", escape_element_name(element_name))
912 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
913
914 let emitting_new_default_ns = if let Some(ns_uri) = ns_all {
918 let dominated = self
919 .current_default_ns
920 .as_ref()
921 .is_some_and(|current| current == ns_uri);
922 if !dominated {
923 write!(self.writer, " xmlns=\"{}\"", escape_attribute_value(ns_uri))
924 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
925 true
926 } else {
927 false
928 }
929 } else {
930 false
931 };
932
933 for (prefix, uri) in &xmlns_decls {
935 write!(
936 self.writer,
937 " xmlns:{}=\"{}\"",
938 escape_element_name(prefix),
939 escape_attribute_value(uri)
940 )
941 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
942 }
943
944 for (attr, prefix) in attributes.iter().zip(attr_prefixes.iter()) {
946 let attr_name = if let Some(p) = prefix {
947 format!("{p}:{}", attr.name)
948 } else {
949 attr.name.to_string()
950 };
951 write!(
952 self.writer,
953 " {}=\"{}\"",
954 escape_element_name(&attr_name),
955 escape_attribute_value(&attr.value)
956 )
957 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
958 }
959
960 if !has_content {
961 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
963 return Ok(());
964 }
965
966 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
967
968 let old_default_ns = if emitting_new_default_ns {
970 let old = self.current_default_ns.take();
971 self.current_default_ns = ns_all.map(|s| s.to_string());
972 old
973 } else {
974 None
975 };
976
977 if let Some(text_peek) = text_content {
979 self.serialize_text_value(text_peek)?;
980 }
981
982 let has_child_elements = !elements.is_empty() || !elements_list.is_empty();
984
985 if has_child_elements {
989 self.depth += 1;
990 }
991
992 for (field_item, field_peek) in elements {
993 let field_ns = Self::get_field_namespace(&field_item.field, ns_all, false);
995
996 self.write_newline()?;
997 self.write_indent()?;
998
999 if field_item.field.proxy_convert_out_fn().is_some() {
1001 if let Ok(owned) = field_peek.custom_serialization(field_item.field) {
1002 self.serialize_namespaced_element(
1003 field_item.name,
1004 owned.as_peek(),
1005 field_ns,
1006 ns_all,
1007 )?;
1008 } else {
1009 self.serialize_namespaced_element(
1010 field_item.name,
1011 field_peek,
1012 field_ns,
1013 ns_all,
1014 )?;
1015 }
1016 } else {
1017 self.serialize_namespaced_element(field_item.name, field_peek, field_ns, ns_all)?;
1018 }
1019 }
1020
1021 for field_peek in elements_list {
1023 self.serialize_elements_list(field_peek)?;
1024 }
1025
1026 if has_child_elements {
1027 self.depth -= 1;
1028 self.write_newline()?;
1029 self.write_indent()?;
1030 }
1031
1032 if emitting_new_default_ns {
1034 self.current_default_ns = old_default_ns;
1035 }
1036
1037 write!(self.writer, "</{}>", escape_element_name(element_name))
1039 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1040
1041 Ok(())
1042 }
1043
1044 fn serialize_namespaced_element<'mem, 'facet>(
1053 &mut self,
1054 element_name: &str,
1055 peek: Peek<'mem, 'facet>,
1056 namespace: Option<&str>,
1057 default_ns: Option<&str>,
1058 ) -> Result<()> {
1059 if let Ok(opt_peek) = peek.into_option() {
1061 if opt_peek.is_none() {
1062 return Ok(());
1063 }
1064 if let Some(inner) = opt_peek.value() {
1065 return self.serialize_namespaced_element(
1066 element_name,
1067 inner,
1068 namespace,
1069 default_ns,
1070 );
1071 }
1072 return Ok(());
1073 }
1074
1075 if is_spanned_shape(peek.shape())
1077 && let Ok(struct_peek) = peek.into_struct()
1078 && let Ok(value_field) = struct_peek.field_by_name("value")
1079 {
1080 return self.serialize_namespaced_element(
1081 element_name,
1082 value_field,
1083 namespace,
1084 default_ns,
1085 );
1086 }
1087
1088 let (final_name, xmlns_decl) = if let Some(ns_uri) = namespace {
1092 if default_ns == Some(ns_uri) {
1093 (element_name.to_string(), None)
1095 } else {
1096 let prefix = self.get_or_create_prefix(ns_uri);
1098 let prefixed = format!("{prefix}:{element_name}");
1099 (prefixed, Some((prefix, ns_uri.to_string())))
1100 }
1101 } else {
1102 (element_name.to_string(), None)
1103 };
1104
1105 let shape = peek.shape();
1107 if let Ok(struct_peek) = peek.into_struct() {
1108 return self.serialize_struct_as_namespaced_element(
1109 &final_name,
1110 struct_peek,
1111 xmlns_decl,
1112 shape,
1113 default_ns,
1114 );
1115 }
1116
1117 if let Ok(enum_peek) = peek.into_enum() {
1119 return self.serialize_enum_as_namespaced_element(&final_name, enum_peek, xmlns_decl);
1120 }
1121
1122 write!(self.writer, "<{}", escape_element_name(&final_name))
1124 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1125
1126 if let Some((prefix, uri)) = xmlns_decl {
1128 write!(
1129 self.writer,
1130 " xmlns:{}=\"{}\"",
1131 escape_element_name(&prefix),
1132 escape_attribute_value(&uri)
1133 )
1134 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1135 }
1136
1137 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1138 self.serialize_value(peek)?;
1139 write!(self.writer, "</{}>", escape_element_name(&final_name))
1140 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1141
1142 Ok(())
1143 }
1144
1145 fn serialize_struct_as_namespaced_element<'mem, 'facet>(
1149 &mut self,
1150 element_name: &str,
1151 struct_peek: facet_reflect::PeekStruct<'mem, 'facet>,
1152 xmlns_decl: Option<(String, String)>,
1153 shape: &'static Shape,
1154 parent_default_ns: Option<&str>,
1155 ) -> Result<()> {
1156 match struct_peek.ty().kind {
1157 StructKind::Unit => {
1158 write!(self.writer, "<{}", escape_element_name(element_name))
1160 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1161 if let Some((prefix, uri)) = xmlns_decl {
1162 write!(
1163 self.writer,
1164 " xmlns:{}=\"{}\"",
1165 escape_element_name(&prefix),
1166 escape_attribute_value(&uri)
1167 )
1168 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1169 }
1170 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1171 return Ok(());
1172 }
1173 StructKind::Tuple | StructKind::TupleStruct => {
1174 let fields: Vec<_> = struct_peek.fields_for_serialize().collect();
1176 if fields.is_empty() {
1177 write!(self.writer, "<{}", escape_element_name(element_name))
1178 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1179 if let Some((prefix, uri)) = xmlns_decl {
1180 write!(
1181 self.writer,
1182 " xmlns:{}=\"{}\"",
1183 escape_element_name(&prefix),
1184 escape_attribute_value(&uri)
1185 )
1186 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1187 }
1188 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1189 return Ok(());
1190 }
1191
1192 write!(self.writer, "<{}", escape_element_name(element_name))
1193 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1194 if let Some((prefix, uri)) = xmlns_decl {
1195 write!(
1196 self.writer,
1197 " xmlns:{}=\"{}\"",
1198 escape_element_name(&prefix),
1199 escape_attribute_value(&uri)
1200 )
1201 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1202 }
1203 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1204
1205 for (i, (_, field_peek)) in fields.into_iter().enumerate() {
1206 let field_name = format!("_{i}");
1207 self.serialize_element(&field_name, field_peek)?;
1208 }
1209
1210 write!(self.writer, "</{}>", escape_element_name(element_name))
1211 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1212 return Ok(());
1213 }
1214 StructKind::Struct => {
1215 }
1217 }
1218
1219 let ns_all = shape.xml_ns_all();
1221
1222 let effective_default_ns: Option<&str> = parent_default_ns;
1227
1228 struct AttrInfo<'a> {
1230 name: &'a str,
1231 value: String,
1232 namespace: Option<&'static str>,
1233 }
1234 let mut attributes: Vec<AttrInfo> = Vec::new();
1235 let mut elements: Vec<(facet_reflect::FieldItem, Peek<'mem, 'facet>)> = Vec::new();
1236 let mut elements_list: Vec<Peek<'mem, 'facet>> = Vec::new();
1237 let mut text_content: Option<Peek<'mem, 'facet>> = None;
1238
1239 for (field_item, field_peek) in struct_peek.fields_for_serialize() {
1240 let field = &field_item.field;
1241
1242 if field.is_xml_attribute() {
1243 let value = if field.proxy_convert_out_fn().is_some() {
1244 if let Ok(owned) = field_peek.custom_serialization(*field) {
1245 value_to_string(owned.as_peek(), self.float_formatter)
1246 } else {
1247 value_to_string(field_peek, self.float_formatter)
1248 }
1249 } else {
1250 value_to_string(field_peek, self.float_formatter)
1251 };
1252 if let Some(value) = value {
1253 let namespace = Self::get_field_namespace(field, ns_all, true);
1255 attributes.push(AttrInfo {
1256 name: field_item.name,
1257 value,
1258 namespace,
1259 });
1260 }
1261 } else if field.is_xml_element() {
1262 elements.push((field_item, field_peek));
1263 } else if field.is_xml_elements() {
1264 elements_list.push(field_peek);
1265 } else if field.is_xml_text() {
1266 text_content = Some(field_peek);
1267 }
1268 }
1269
1270 let has_content =
1271 !elements.is_empty() || !elements_list.is_empty() || text_content.is_some();
1272
1273 let mut xmlns_decls: Vec<(String, String)> = Vec::new();
1276 let mut attr_prefixes: Vec<Option<String>> = Vec::new();
1277
1278 if let Some((prefix, uri)) = xmlns_decl {
1280 xmlns_decls.push((prefix, uri));
1281 }
1282
1283 for attr in &attributes {
1284 if let Some(ns_uri) = attr.namespace {
1285 let prefix = self.get_or_create_prefix(ns_uri);
1286 if !xmlns_decls.iter().any(|(_, u)| u == ns_uri) {
1288 xmlns_decls.push((prefix.clone(), ns_uri.to_string()));
1289 }
1290 attr_prefixes.push(Some(prefix));
1291 } else {
1292 attr_prefixes.push(None);
1293 }
1294 }
1295
1296 write!(self.writer, "<{}", escape_element_name(element_name))
1298 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1299
1300 for (prefix, uri) in &xmlns_decls {
1307 write!(
1308 self.writer,
1309 " xmlns:{}=\"{}\"",
1310 escape_element_name(prefix),
1311 escape_attribute_value(uri)
1312 )
1313 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1314 }
1315
1316 for (attr, prefix) in attributes.iter().zip(attr_prefixes.iter()) {
1318 let attr_name = if let Some(p) = prefix {
1319 format!("{p}:{}", attr.name)
1320 } else {
1321 attr.name.to_string()
1322 };
1323 write!(
1324 self.writer,
1325 " {}=\"{}\"",
1326 escape_element_name(&attr_name),
1327 escape_attribute_value(&attr.value)
1328 )
1329 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1330 }
1331
1332 if !has_content {
1333 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1334 return Ok(());
1335 }
1336
1337 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1338
1339 if let Some(text_peek) = text_content {
1340 self.serialize_text_value(text_peek)?;
1341 }
1342
1343 let has_child_elements = !elements.is_empty() || !elements_list.is_empty();
1345
1346 if has_child_elements {
1347 self.depth += 1;
1348 }
1349
1350 for (field_item, field_peek) in elements {
1351 let field_ns = Self::get_field_namespace(&field_item.field, ns_all, false);
1353
1354 self.write_newline()?;
1355 self.write_indent()?;
1356
1357 if field_item.field.proxy_convert_out_fn().is_some() {
1358 if let Ok(owned) = field_peek.custom_serialization(field_item.field) {
1359 self.serialize_namespaced_element(
1360 field_item.name,
1361 owned.as_peek(),
1362 field_ns,
1363 effective_default_ns,
1364 )?;
1365 } else {
1366 self.serialize_namespaced_element(
1367 field_item.name,
1368 field_peek,
1369 field_ns,
1370 effective_default_ns,
1371 )?;
1372 }
1373 } else {
1374 self.serialize_namespaced_element(
1375 field_item.name,
1376 field_peek,
1377 field_ns,
1378 effective_default_ns,
1379 )?;
1380 }
1381 }
1382
1383 for field_peek in elements_list {
1384 self.serialize_elements_list(field_peek)?;
1385 }
1386
1387 if has_child_elements {
1388 self.depth -= 1;
1389 self.write_newline()?;
1390 self.write_indent()?;
1391 }
1392
1393 write!(self.writer, "</{}>", escape_element_name(element_name))
1394 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1395
1396 Ok(())
1397 }
1398
1399 fn serialize_enum_as_namespaced_element<'mem, 'facet>(
1401 &mut self,
1402 prefixed_element_name: &str,
1403 enum_peek: facet_reflect::PeekEnum<'mem, 'facet>,
1404 xmlns_decl: Option<(String, String)>,
1405 ) -> Result<()> {
1406 let shape = enum_peek.shape();
1407 let variant_name = enum_peek
1408 .variant_name_active()
1409 .map_err(|_| XmlErrorKind::SerializeUnknownElementType)?;
1410
1411 let fields: Vec<_> = enum_peek.fields_for_serialize().collect();
1412
1413 let is_untagged = shape.is_untagged();
1414 let tag_attr = shape.get_tag_attr();
1415 let content_attr = shape.get_content_attr();
1416
1417 let write_open_tag =
1419 |writer: &mut W, name: &str, xmlns: &Option<(String, String)>| -> Result<()> {
1420 write!(writer, "<{}", escape_element_name(name))
1421 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1422 if let Some((prefix, uri)) = xmlns {
1423 write!(
1424 writer,
1425 " xmlns:{}=\"{}\"",
1426 escape_element_name(prefix),
1427 escape_attribute_value(uri)
1428 )
1429 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1430 }
1431 Ok(())
1432 };
1433
1434 if is_untagged {
1435 if fields.is_empty() {
1437 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1438 write!(self.writer, "/>").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1439 } else if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
1440 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1442 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1443 self.serialize_value(fields[0].1)?;
1444 write!(
1445 self.writer,
1446 "</{}>",
1447 escape_element_name(prefixed_element_name)
1448 )
1449 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1450 } else {
1451 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1452 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1453 for (field_item, field_peek) in fields {
1454 self.serialize_element(field_item.name, field_peek)?;
1455 }
1456 write!(
1457 self.writer,
1458 "</{}>",
1459 escape_element_name(prefixed_element_name)
1460 )
1461 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1462 }
1463 } else if let Some(tag) = tag_attr {
1464 if let Some(content) = content_attr {
1465 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1467 write!(
1468 self.writer,
1469 " {}=\"{}\">",
1470 escape_element_name(tag),
1471 escape_attribute_value(variant_name)
1472 )
1473 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1474
1475 if !fields.is_empty() {
1476 write!(self.writer, "<{}>", escape_element_name(content))
1477 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1478 self.serialize_variant_fields(&fields)?;
1479 write!(self.writer, "</{}>", escape_element_name(content))
1480 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1481 }
1482
1483 write!(
1484 self.writer,
1485 "</{}>",
1486 escape_element_name(prefixed_element_name)
1487 )
1488 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1489 } else {
1490 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1492 write!(
1493 self.writer,
1494 " {}=\"{}\">",
1495 escape_element_name(tag),
1496 escape_attribute_value(variant_name)
1497 )
1498 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1499 self.serialize_variant_fields(&fields)?;
1500 write!(
1501 self.writer,
1502 "</{}>",
1503 escape_element_name(prefixed_element_name)
1504 )
1505 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1506 }
1507 } else {
1508 write_open_tag(&mut self.writer, prefixed_element_name, &xmlns_decl)?;
1510 write!(self.writer, ">").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1511
1512 if fields.is_empty() {
1513 write!(self.writer, "<{}/>", escape_element_name(variant_name))
1514 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1515 } else if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
1516 self.serialize_element(variant_name, fields[0].1)?;
1517 } else {
1518 write!(self.writer, "<{}>", escape_element_name(variant_name))
1519 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1520 for (field_item, field_peek) in fields {
1521 self.serialize_element(field_item.name, field_peek)?;
1522 }
1523 write!(self.writer, "</{}>", escape_element_name(variant_name))
1524 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1525 }
1526
1527 write!(
1528 self.writer,
1529 "</{}>",
1530 escape_element_name(prefixed_element_name)
1531 )
1532 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1533 }
1534
1535 Ok(())
1536 }
1537
1538 fn serialize_elements_list<'mem, 'facet>(&mut self, peek: Peek<'mem, 'facet>) -> Result<()> {
1539 let list_peek = peek
1540 .into_list()
1541 .map_err(|_| XmlErrorKind::SerializeNotList)?;
1542
1543 for item_peek in list_peek.iter() {
1544 self.write_newline()?;
1545 self.write_indent()?;
1546 self.serialize_list_item_element(item_peek)?;
1547 }
1548
1549 Ok(())
1550 }
1551
1552 fn serialize_list_item_element<'mem, 'facet>(
1553 &mut self,
1554 peek: Peek<'mem, 'facet>,
1555 ) -> Result<()> {
1556 if let Ok(enum_peek) = peek.into_enum() {
1558 let variant_name = enum_peek
1559 .variant_name_active()
1560 .map_err(|_| XmlErrorKind::SerializeUnknownElementType)?;
1561
1562 let fields: Vec<_> = enum_peek.fields_for_serialize().collect();
1564
1565 if fields.is_empty() {
1566 write!(self.writer, "<{}/>", escape_element_name(variant_name))
1568 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1569 } else if fields.len() == 1 && fields[0].0.name.parse::<usize>().is_ok() {
1570 self.serialize_element(variant_name, fields[0].1)?;
1572 } else {
1573 write!(self.writer, "<{}>", escape_element_name(variant_name))
1575 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1576
1577 for (field_item, field_peek) in fields {
1578 self.serialize_element(field_item.name, field_peek)?;
1579 }
1580
1581 write!(self.writer, "</{}>", escape_element_name(variant_name))
1582 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1583 }
1584 return Ok(());
1585 }
1586
1587 let type_name = peek.shape().type_identifier;
1589 self.serialize_element(type_name, peek)
1590 }
1591
1592 fn serialize_text_value<'mem, 'facet>(&mut self, peek: Peek<'mem, 'facet>) -> Result<()> {
1593 if let Ok(opt_peek) = peek.into_option() {
1595 if opt_peek.is_none() {
1596 return Ok(());
1597 }
1598 if let Some(inner) = opt_peek.value() {
1599 return self.serialize_text_value(inner);
1600 }
1601 return Ok(());
1602 }
1603
1604 if is_spanned_shape(peek.shape())
1606 && let Ok(struct_peek) = peek.into_struct()
1607 && let Ok(value_peek) = struct_peek.field_by_name("value")
1608 {
1609 return self.serialize_text_value(value_peek);
1610 }
1611
1612 self.serialize_value(peek)
1613 }
1614
1615 fn serialize_value<'mem, 'facet>(&mut self, peek: Peek<'mem, 'facet>) -> Result<()> {
1616 if let Ok(opt_peek) = peek.into_option() {
1618 if opt_peek.is_none() {
1619 return Ok(());
1620 }
1621 if let Some(inner) = opt_peek.value() {
1622 return self.serialize_value(inner);
1623 }
1624 return Ok(());
1625 }
1626
1627 if is_spanned_shape(peek.shape())
1629 && let Ok(struct_peek) = peek.into_struct()
1630 && let Ok(value_peek) = struct_peek.field_by_name("value")
1631 {
1632 return self.serialize_value(value_peek);
1633 }
1634
1635 let peek = peek.innermost_peek();
1637
1638 if let Some(s) = peek.as_str() {
1640 write!(self.writer, "{}", escape_text(s))
1641 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1642 return Ok(());
1643 }
1644
1645 if let Ok(v) = peek.get::<bool>() {
1647 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1648 return Ok(());
1649 }
1650
1651 if let Ok(v) = peek.get::<i8>() {
1652 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1653 return Ok(());
1654 }
1655 if let Ok(v) = peek.get::<i16>() {
1656 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1657 return Ok(());
1658 }
1659 if let Ok(v) = peek.get::<i32>() {
1660 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1661 return Ok(());
1662 }
1663 if let Ok(v) = peek.get::<i64>() {
1664 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1665 return Ok(());
1666 }
1667
1668 if let Ok(v) = peek.get::<u8>() {
1669 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1670 return Ok(());
1671 }
1672 if let Ok(v) = peek.get::<u16>() {
1673 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1674 return Ok(());
1675 }
1676 if let Ok(v) = peek.get::<u32>() {
1677 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1678 return Ok(());
1679 }
1680 if let Ok(v) = peek.get::<u64>() {
1681 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1682 return Ok(());
1683 }
1684
1685 if let Ok(v) = peek.get::<f32>() {
1686 if let Some(fmt) = self.float_formatter {
1687 fmt(f64::from(*v), &mut self.writer)
1688 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1689 } else {
1690 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1691 }
1692 return Ok(());
1693 }
1694 if let Ok(v) = peek.get::<f64>() {
1695 if let Some(fmt) = self.float_formatter {
1696 fmt(*v, &mut self.writer).map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1697 } else {
1698 write!(self.writer, "{v}").map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1699 }
1700 return Ok(());
1701 }
1702
1703 if let Ok(v) = peek.get::<char>() {
1704 write!(self.writer, "{}", escape_text(&v.to_string()))
1705 .map_err(|e| XmlErrorKind::Io(e.to_string()))?;
1706 return Ok(());
1707 }
1708
1709 Err(XmlErrorKind::SerializeUnknownValueType.into())
1710 }
1711}
1712
1713fn value_to_string<'mem, 'facet>(
1715 peek: Peek<'mem, 'facet>,
1716 float_formatter: Option<FloatFormatter>,
1717) -> Option<String> {
1718 if let Ok(opt_peek) = peek.into_option() {
1720 if opt_peek.is_none() {
1721 return None;
1722 }
1723 if let Some(inner) = opt_peek.value() {
1724 return value_to_string(inner, float_formatter);
1725 }
1726 return None;
1727 }
1728
1729 if is_spanned_shape(peek.shape())
1731 && let Ok(struct_peek) = peek.into_struct()
1732 && let Ok(value_peek) = struct_peek.field_by_name("value")
1733 {
1734 return value_to_string(value_peek, float_formatter);
1735 }
1736
1737 let peek = peek.innermost_peek();
1739
1740 if let Some(s) = peek.as_str() {
1742 return Some(s.to_string());
1743 }
1744
1745 if let Ok(v) = peek.get::<bool>() {
1747 return Some(v.to_string());
1748 }
1749
1750 if let Ok(v) = peek.get::<i8>() {
1751 return Some(v.to_string());
1752 }
1753 if let Ok(v) = peek.get::<i16>() {
1754 return Some(v.to_string());
1755 }
1756 if let Ok(v) = peek.get::<i32>() {
1757 return Some(v.to_string());
1758 }
1759 if let Ok(v) = peek.get::<i64>() {
1760 return Some(v.to_string());
1761 }
1762
1763 if let Ok(v) = peek.get::<u8>() {
1764 return Some(v.to_string());
1765 }
1766 if let Ok(v) = peek.get::<u16>() {
1767 return Some(v.to_string());
1768 }
1769 if let Ok(v) = peek.get::<u32>() {
1770 return Some(v.to_string());
1771 }
1772 if let Ok(v) = peek.get::<u64>() {
1773 return Some(v.to_string());
1774 }
1775
1776 if let Ok(v) = peek.get::<f32>() {
1777 if let Some(fmt) = float_formatter {
1778 let mut buf = Vec::new();
1779 if fmt(f64::from(*v), &mut buf).is_ok() {
1780 return String::from_utf8(buf).ok();
1781 }
1782 }
1783 return Some(v.to_string());
1784 }
1785 if let Ok(v) = peek.get::<f64>() {
1786 if let Some(fmt) = float_formatter {
1787 let mut buf = Vec::new();
1788 if fmt(*v, &mut buf).is_ok() {
1789 return String::from_utf8(buf).ok();
1790 }
1791 }
1792 return Some(v.to_string());
1793 }
1794
1795 if let Ok(v) = peek.get::<char>() {
1796 return Some(v.to_string());
1797 }
1798
1799 None
1800}
1801
1802fn escape_text(s: &str) -> String {
1804 let mut result = String::with_capacity(s.len());
1805 for c in s.chars() {
1806 match c {
1807 '<' => result.push_str("<"),
1808 '>' => result.push_str(">"),
1809 '&' => result.push_str("&"),
1810 _ => result.push(c),
1811 }
1812 }
1813 result
1814}
1815
1816fn escape_attribute_value(s: &str) -> String {
1818 let mut result = String::with_capacity(s.len());
1819 for c in s.chars() {
1820 match c {
1821 '<' => result.push_str("<"),
1822 '>' => result.push_str(">"),
1823 '&' => result.push_str("&"),
1824 '"' => result.push_str("""),
1825 '\'' => result.push_str("'"),
1826 _ => result.push(c),
1827 }
1828 }
1829 result
1830}
1831
1832fn escape_element_name(name: &str) -> &str {
1834 name
1835}