1extern crate alloc;
2
3use alloc::borrow::Cow;
4use alloc::string::String;
5use core::fmt::Debug;
6use core::fmt::Write as _;
7
8use facet_core::{
9 Def, DynDateTimeKind, DynValueKind, ScalarType, Shape, StructKind, Type, UserType,
10};
11use facet_reflect::{HasFields as _, Peek, ReflectError};
12
13use crate::ScalarValue;
14
15fn extract_string_from_peek<'mem, 'facet>(peek: Peek<'mem, 'facet>) -> Option<&'mem str> {
20 if let Some(s) = peek.as_str() {
22 return Some(s);
23 }
24
25 if peek.shape().is_metadata_container()
27 && let Type::User(UserType::Struct(st)) = &peek.shape().ty
28 {
29 for field in st.fields {
31 if field.metadata_kind().is_none() {
32 if let Ok(container) = peek.into_struct() {
34 for (f, field_value) in container.fields() {
35 if f.metadata_kind().is_none() {
36 return extract_string_from_peek(field_value);
38 }
39 }
40 }
41 break;
42 }
43 }
44 }
45
46 None
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
51pub enum FieldOrdering {
52 #[default]
54 Declaration,
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
59pub enum StructFieldMode {
60 #[default]
62 Named,
63 Unnamed,
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
69pub enum MapEncoding {
70 #[default]
72 Struct,
73 Pairs,
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
79pub enum EnumVariantEncoding {
80 #[default]
82 Tagged,
83 Index,
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
89pub enum DynamicValueEncoding {
90 #[default]
92 SelfDescribing,
93 Tagged,
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq)]
99pub enum DynamicValueTag {
100 Null,
102 Bool,
104 I64,
106 U64,
108 F64,
110 String,
112 Bytes,
114 Array,
116 Object,
118 DateTime,
120}
121
122pub trait FormatSerializer {
127 type Error: Debug;
129
130 fn begin_struct(&mut self) -> Result<(), Self::Error>;
132 fn field_key(&mut self, key: &str) -> Result<(), Self::Error>;
134 fn emit_field_key(&mut self, key: &crate::FieldKey<'_>) -> Result<(), Self::Error> {
142 let name = key.name().map(|c| c.as_ref()).unwrap_or("");
144 self.field_key(name)
145 }
146 fn end_struct(&mut self) -> Result<(), Self::Error>;
148
149 fn begin_seq(&mut self) -> Result<(), Self::Error>;
151 fn end_seq(&mut self) -> Result<(), Self::Error>;
153
154 fn scalar(&mut self, scalar: ScalarValue<'_>) -> Result<(), Self::Error>;
156
157 fn field_metadata(&mut self, _field: &facet_reflect::FieldItem) -> Result<(), Self::Error> {
160 Ok(())
161 }
162
163 fn field_metadata_with_value(
174 &mut self,
175 _field: &facet_reflect::FieldItem,
176 _value: Peek<'_, '_>,
177 ) -> Result<bool, Self::Error> {
178 Ok(false)
179 }
180
181 fn struct_metadata(&mut self, _shape: &facet_core::Shape) -> Result<(), Self::Error> {
184 Ok(())
185 }
186
187 fn variant_metadata(
190 &mut self,
191 _variant: &'static facet_core::Variant,
192 ) -> Result<(), Self::Error> {
193 Ok(())
194 }
195
196 fn serialize_metadata_container(
218 &mut self,
219 _container: &facet_reflect::PeekStruct<'_, '_>,
220 ) -> Result<bool, Self::Error> {
221 Ok(false)
222 }
223
224 fn preferred_field_order(&self) -> FieldOrdering {
227 FieldOrdering::Declaration
228 }
229
230 fn struct_field_mode(&self) -> StructFieldMode {
232 StructFieldMode::Named
233 }
234
235 fn map_encoding(&self) -> MapEncoding {
237 MapEncoding::Struct
238 }
239
240 fn enum_variant_encoding(&self) -> EnumVariantEncoding {
242 EnumVariantEncoding::Tagged
243 }
244
245 fn is_self_describing(&self) -> bool {
253 true
254 }
255
256 fn dynamic_value_encoding(&self) -> DynamicValueEncoding {
258 DynamicValueEncoding::SelfDescribing
259 }
260
261 fn raw_serialize_shape(&self) -> Option<&'static facet_core::Shape> {
267 None
268 }
269
270 fn raw_scalar(&mut self, content: &str) -> Result<(), Self::Error> {
275 self.scalar(ScalarValue::Str(Cow::Borrowed(content)))
277 }
278
279 fn serialize_opaque_scalar(
283 &mut self,
284 _shape: &'static facet_core::Shape,
285 _value: Peek<'_, '_>,
286 ) -> Result<bool, Self::Error> {
287 Ok(false)
288 }
289
290 fn serialize_opaque_scalar_with_field(
295 &mut self,
296 _field: Option<&facet_core::Field>,
297 shape: &'static facet_core::Shape,
298 value: Peek<'_, '_>,
299 ) -> Result<bool, Self::Error> {
300 self.serialize_opaque_scalar(shape, value)
301 }
302
303 fn dynamic_value_tag(&mut self, _tag: DynamicValueTag) -> Result<(), Self::Error> {
308 Ok(())
309 }
310
311 fn begin_seq_with_len(&mut self, _len: usize) -> Result<(), Self::Error> {
328 self.begin_seq()
329 }
330
331 fn begin_map_with_len(&mut self, _len: usize) -> Result<(), Self::Error> {
335 self.begin_struct()
336 }
337
338 fn end_map(&mut self) -> Result<(), Self::Error> {
342 self.end_struct()
343 }
344
345 fn serialize_map_key(&mut self, _key: Peek<'_, '_>) -> Result<bool, Self::Error> {
356 Ok(false)
357 }
358
359 fn typed_scalar(
369 &mut self,
370 scalar_type: ScalarType,
371 value: Peek<'_, '_>,
372 ) -> Result<(), Self::Error> {
373 let scalar = match scalar_type {
375 ScalarType::Unit => ScalarValue::Null,
376 ScalarType::Bool => ScalarValue::Bool(*value.get::<bool>().unwrap()),
377 ScalarType::Char => ScalarValue::Char(*value.get::<char>().unwrap()),
378 ScalarType::Str | ScalarType::String | ScalarType::CowStr => {
379 ScalarValue::Str(Cow::Borrowed(value.as_str().unwrap()))
380 }
381 ScalarType::F32 => ScalarValue::F64(*value.get::<f32>().unwrap() as f64),
382 ScalarType::F64 => ScalarValue::F64(*value.get::<f64>().unwrap()),
383 ScalarType::U8 => ScalarValue::U64(*value.get::<u8>().unwrap() as u64),
384 ScalarType::U16 => ScalarValue::U64(*value.get::<u16>().unwrap() as u64),
385 ScalarType::U32 => ScalarValue::U64(*value.get::<u32>().unwrap() as u64),
386 ScalarType::U64 => ScalarValue::U64(*value.get::<u64>().unwrap()),
387 ScalarType::U128 => {
388 let n = *value.get::<u128>().unwrap();
389 ScalarValue::Str(Cow::Owned(alloc::string::ToString::to_string(&n)))
390 }
391 ScalarType::USize => ScalarValue::U64(*value.get::<usize>().unwrap() as u64),
392 ScalarType::I8 => ScalarValue::I64(*value.get::<i8>().unwrap() as i64),
393 ScalarType::I16 => ScalarValue::I64(*value.get::<i16>().unwrap() as i64),
394 ScalarType::I32 => ScalarValue::I64(*value.get::<i32>().unwrap() as i64),
395 ScalarType::I64 => ScalarValue::I64(*value.get::<i64>().unwrap()),
396 ScalarType::I128 => {
397 let n = *value.get::<i128>().unwrap();
398 ScalarValue::Str(Cow::Owned(alloc::string::ToString::to_string(&n)))
399 }
400 ScalarType::ISize => ScalarValue::I64(*value.get::<isize>().unwrap() as i64),
401 #[cfg(feature = "net")]
402 ScalarType::IpAddr => {
403 let addr = *value.get::<core::net::IpAddr>().unwrap();
404 ScalarValue::Str(Cow::Owned(alloc::string::ToString::to_string(&addr)))
405 }
406 #[cfg(feature = "net")]
407 ScalarType::Ipv4Addr => {
408 let addr = *value.get::<core::net::Ipv4Addr>().unwrap();
409 ScalarValue::Str(Cow::Owned(alloc::string::ToString::to_string(&addr)))
410 }
411 #[cfg(feature = "net")]
412 ScalarType::Ipv6Addr => {
413 let addr = *value.get::<core::net::Ipv6Addr>().unwrap();
414 ScalarValue::Str(Cow::Owned(alloc::string::ToString::to_string(&addr)))
415 }
416 #[cfg(feature = "net")]
417 ScalarType::SocketAddr => {
418 let addr = *value.get::<core::net::SocketAddr>().unwrap();
419 ScalarValue::Str(Cow::Owned(alloc::string::ToString::to_string(&addr)))
420 }
421 _ => {
422 if let Some(s) = value.as_str() {
424 ScalarValue::Str(Cow::Borrowed(s))
425 } else {
426 ScalarValue::Null
427 }
428 }
429 };
430 self.scalar(scalar)
431 }
432
433 fn begin_option_some(&mut self) -> Result<(), Self::Error> {
440 Ok(())
441 }
442
443 fn serialize_none(&mut self) -> Result<(), Self::Error> {
450 self.scalar(ScalarValue::Null)
451 }
452
453 fn begin_enum_variant(
463 &mut self,
464 _variant_index: usize,
465 _variant_name: &'static str,
466 ) -> Result<(), Self::Error> {
467 Ok(())
468 }
469
470 fn write_variant_tag(&mut self, _variant_name: &str) -> Result<bool, Self::Error> {
484 Ok(false)
485 }
486
487 fn begin_struct_after_tag(&mut self) -> Result<(), Self::Error> {
494 self.begin_struct()
495 }
496
497 fn begin_seq_after_tag(&mut self) -> Result<(), Self::Error> {
504 self.begin_seq()
505 }
506
507 fn finish_variant_tag_unit_payload(&mut self) -> Result<(), Self::Error> {
519 Ok(())
520 }
521
522 fn serialize_byte_sequence(&mut self, _bytes: &[u8]) -> Result<bool, Self::Error> {
535 Ok(false)
537 }
538
539 fn serialize_byte_array(&mut self, _bytes: &[u8]) -> Result<bool, Self::Error> {
546 Ok(false)
548 }
549
550 fn format_namespace(&self) -> Option<&'static str> {
562 None
563 }
564}
565
566#[derive(Debug)]
568pub enum SerializeError<E: Debug> {
569 Backend(E),
571 Reflect(ReflectError),
573 Unsupported(Cow<'static, str>),
575 Internal(Cow<'static, str>),
577}
578
579impl<E: Debug> core::fmt::Display for SerializeError<E> {
580 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
581 match self {
582 SerializeError::Backend(_) => f.write_str("format serializer error"),
583 SerializeError::Reflect(err) => write!(f, "{err}"),
584 SerializeError::Unsupported(msg) => f.write_str(msg.as_ref()),
585 SerializeError::Internal(msg) => f.write_str(msg.as_ref()),
586 }
587 }
588}
589
590#[derive(Debug, Clone)]
592pub enum PathSegment {
593 Field(Cow<'static, str>),
595 Index(usize),
597 Variant(Cow<'static, str>),
599}
600
601impl core::fmt::Display for PathSegment {
602 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
603 match self {
604 PathSegment::Field(name) => write!(f, ".{}", name),
605 PathSegment::Index(idx) => write!(f, "[{}]", idx),
606 PathSegment::Variant(name) => write!(f, "::{}", name),
607 }
608 }
609}
610
611pub struct SerializeContext<'s, S: FormatSerializer> {
616 serializer: &'s mut S,
617 path: alloc::vec::Vec<PathSegment>,
618 current_field: Option<facet_core::Field>,
619}
620
621impl<'s, S: FormatSerializer> SerializeContext<'s, S> {
622 pub fn new(serializer: &'s mut S) -> Self {
624 Self {
625 serializer,
626 path: alloc::vec::Vec::new(),
627 current_field: None,
628 }
629 }
630
631 fn with_field_context<T>(
632 &mut self,
633 field: Option<facet_core::Field>,
634 f: impl FnOnce(&mut Self) -> T,
635 ) -> T {
636 let prev = self.current_field;
637 self.current_field = field;
638 let out = f(self);
639 self.current_field = prev;
640 out
641 }
642
643 fn push(&mut self, segment: PathSegment) {
645 self.path.push(segment);
646 }
647
648 fn pop(&mut self) {
650 self.path.pop();
651 }
652
653 fn path_string(&self) -> String {
655 if self.path.is_empty() {
656 "<root>".into()
657 } else {
658 let mut s = String::new();
659 for seg in &self.path {
660 let _ = write!(s, "{}", seg);
661 }
662 s
663 }
664 }
665
666 fn unsupported_error(&self, shape: &Shape, msg: &str) -> SerializeError<S::Error> {
668 SerializeError::Unsupported(Cow::Owned(alloc::format!(
669 "{} (type: `{}`, def: {}, path: `{}`)",
670 msg,
671 shape,
672 def_kind_name(&shape.def),
673 self.path_string()
674 )))
675 }
676
677 pub fn serialize<'mem, 'facet>(
679 &mut self,
680 value: Peek<'mem, 'facet>,
681 ) -> Result<(), SerializeError<S::Error>> {
682 self.serialize_impl(value)
683 }
684
685 fn serialize_impl<'mem, 'facet>(
686 &mut self,
687 value: Peek<'mem, 'facet>,
688 ) -> Result<(), SerializeError<S::Error>> {
689 let value = deref_if_pointer(value);
691
692 if self.serializer.raw_serialize_shape() == Some(value.shape()) {
694 if let Ok(struct_) = value.into_struct()
695 && let Some((_field_item, inner_value)) =
696 struct_.fields_for_binary_serialize().next()
697 && let Some(s) = inner_value.as_str()
698 {
699 return self
700 .serializer
701 .raw_scalar(s)
702 .map_err(SerializeError::Backend);
703 }
704 return Err(SerializeError::Unsupported(Cow::Borrowed(
705 "raw capture type matched but could not extract inner string",
706 )));
707 }
708
709 if self
710 .serializer
711 .serialize_opaque_scalar_with_field(self.current_field.as_ref(), value.shape(), value)
712 .map_err(SerializeError::Backend)?
713 {
714 return Ok(());
715 }
716
717 let value = value.innermost_peek();
718
719 if value.shape().is_metadata_container()
721 && let Ok(struct_) = value.into_struct()
722 {
723 if self
724 .serializer
725 .serialize_metadata_container(&struct_)
726 .map_err(SerializeError::Backend)?
727 {
728 return Ok(());
729 }
730 for (field, field_value) in struct_.fields() {
731 if !field.is_metadata() {
732 return self.serialize_impl(field_value);
733 }
734 }
735 }
736
737 if let Some(proxy_def) = value
739 .shape()
740 .effective_proxy(self.serializer.format_namespace())
741 {
742 return self.serialize_via_proxy(value, proxy_def);
743 }
744
745 if let Some(scalar_type) = value.scalar_type() {
747 return self
748 .serializer
749 .typed_scalar(scalar_type, value)
750 .map_err(SerializeError::Backend);
751 }
752
753 if matches!(value.shape().def, Def::Scalar) && value.shape().vtable.has_display() {
755 use alloc::string::ToString;
756 let formatted = value.to_string();
757 return self
758 .serializer
759 .scalar(ScalarValue::Str(Cow::Owned(formatted)))
760 .map_err(SerializeError::Backend);
761 }
762
763 if let Ok(opt) = value.into_option() {
765 return match opt.value() {
766 Some(inner) => {
767 self.serializer
768 .begin_option_some()
769 .map_err(SerializeError::Backend)?;
770 self.serialize_impl(inner)
771 }
772 None => self
773 .serializer
774 .serialize_none()
775 .map_err(SerializeError::Backend),
776 };
777 }
778
779 if let Ok(result) = value.into_result() {
780 let (variant_index, variant_name, inner) = if result.is_ok() {
781 (
782 0,
783 "Ok",
784 result.ok().ok_or(SerializeError::Internal(Cow::Borrowed(
785 "result reported Ok but value was missing",
786 )))?,
787 )
788 } else {
789 (
790 1,
791 "Err",
792 result.err().ok_or(SerializeError::Internal(Cow::Borrowed(
793 "result reported Err but value was missing",
794 )))?,
795 )
796 };
797
798 if self.serializer.enum_variant_encoding() == EnumVariantEncoding::Index {
799 self.serializer
800 .begin_enum_variant(variant_index, variant_name)
801 .map_err(SerializeError::Backend)?;
802 self.push(PathSegment::Variant(Cow::Borrowed(variant_name)));
803 let result = self.serialize_impl(inner);
804 self.pop();
805 return result;
806 }
807
808 self.serializer
809 .begin_struct()
810 .map_err(SerializeError::Backend)?;
811 self.serializer
812 .field_key(variant_name)
813 .map_err(SerializeError::Backend)?;
814 self.push(PathSegment::Variant(Cow::Borrowed(variant_name)));
815 let result = self.serialize_impl(inner);
816 self.pop();
817 result?;
818 self.serializer
819 .end_struct()
820 .map_err(SerializeError::Backend)?;
821 return Ok(());
822 }
823
824 if let Ok(dynamic) = value.into_dynamic_value() {
825 return self.serialize_dynamic_value(dynamic);
826 }
827
828 match value.shape().def {
829 facet_core::Def::List(_) | facet_core::Def::Array(_) | facet_core::Def::Slice(_) => {
830 let list = value.into_list_like().map_err(SerializeError::Reflect)?;
831 let len = list.len();
832
833 if let Some(bytes) = list.as_bytes() {
835 let handled = match value.shape().def {
836 facet_core::Def::Array(_) => self
837 .serializer
838 .serialize_byte_array(bytes)
839 .map_err(SerializeError::Backend)?,
840 _ => self
841 .serializer
842 .serialize_byte_sequence(bytes)
843 .map_err(SerializeError::Backend)?,
844 };
845 if handled {
846 return Ok(());
847 }
848 }
849
850 match value.shape().def {
851 facet_core::Def::Array(_) => self
852 .serializer
853 .begin_seq()
854 .map_err(SerializeError::Backend)?,
855 _ => self
856 .serializer
857 .begin_seq_with_len(len)
858 .map_err(SerializeError::Backend)?,
859 };
860 for (idx, item) in list.iter().enumerate() {
861 self.push(PathSegment::Index(idx));
862 self.serialize_impl(item)?;
863 self.pop();
864 }
865 self.serializer.end_seq().map_err(SerializeError::Backend)?;
866 return Ok(());
867 }
868 _ => {}
869 }
870
871 if let Ok(map) = value.into_map() {
872 let len = map.len();
873 match self.serializer.map_encoding() {
874 MapEncoding::Pairs => {
875 self.serializer
876 .begin_map_with_len(len)
877 .map_err(SerializeError::Backend)?;
878 for (key, val) in map.iter() {
879 self.serialize_impl(key)?;
880 let key_str = key
882 .as_str()
883 .map(|s| Cow::Owned(s.to_string()))
884 .unwrap_or_else(|| Cow::Owned(alloc::format!("{}", key)));
885 self.push(PathSegment::Field(key_str));
886 self.serialize_impl(val)?;
887 self.pop();
888 }
889 self.serializer.end_map().map_err(SerializeError::Backend)?;
890 }
891 MapEncoding::Struct => {
892 self.serializer
893 .begin_struct()
894 .map_err(SerializeError::Backend)?;
895 for (key, val) in map.iter() {
896 if !self
897 .serializer
898 .serialize_map_key(key)
899 .map_err(SerializeError::Backend)?
900 {
901 let key_str = if let Some(s) = extract_string_from_peek(key) {
903 Cow::Borrowed(s)
904 } else {
905 Cow::Owned(alloc::format!("{}", key))
906 };
907 self.serializer
908 .field_key(&key_str)
909 .map_err(SerializeError::Backend)?;
910 }
911 let key_str = extract_string_from_peek(key)
913 .map(|s| Cow::Owned(s.to_string()))
914 .unwrap_or_else(|| Cow::Owned(alloc::format!("{}", key)));
915 self.push(PathSegment::Field(key_str));
916 self.serialize_impl(val)?;
917 self.pop();
918 }
919 self.serializer
920 .end_struct()
921 .map_err(SerializeError::Backend)?;
922 }
923 }
924 return Ok(());
925 }
926
927 if let Ok(set) = value.into_set() {
928 let len = set.len();
929 self.serializer
930 .begin_seq_with_len(len)
931 .map_err(SerializeError::Backend)?;
932 for (idx, item) in set.iter().enumerate() {
933 self.push(PathSegment::Index(idx));
934 self.serialize_impl(item)?;
935 self.pop();
936 }
937 self.serializer.end_seq().map_err(SerializeError::Backend)?;
938 return Ok(());
939 }
940
941 if let Ok(struct_) = value.into_struct() {
942 return self.serialize_struct(value.shape(), struct_);
943 }
944
945 if let Ok(enum_) = value.into_enum() {
946 return self.serialize_enum(value.shape(), enum_);
947 }
948
949 Err(self.unsupported_error(value.shape(), "unsupported value kind for serialization"))
950 }
951
952 fn serialize_field_value<'mem, 'facet>(
953 &mut self,
954 field_item: &facet_reflect::FieldItem,
955 field_value: Peek<'mem, 'facet>,
956 ) -> Result<(), SerializeError<S::Error>> {
957 self.with_field_context(field_item.field, |this| {
958 if let Some(proxy_def) = field_item
959 .field
960 .and_then(|f| f.effective_proxy(this.serializer.format_namespace()))
961 {
962 this.serialize_via_proxy(field_value, proxy_def)
963 } else {
964 this.serialize_impl(field_value)
965 }
966 })
967 }
968
969 fn serialize_struct<'mem, 'facet>(
970 &mut self,
971 shape: &'static Shape,
972 struct_: facet_reflect::PeekStruct<'mem, 'facet>,
973 ) -> Result<(), SerializeError<S::Error>> {
974 let kind = struct_.ty().kind;
975 let field_mode = self.serializer.struct_field_mode();
976 self.serializer
977 .struct_metadata(shape)
978 .map_err(SerializeError::Backend)?;
979
980 if kind == StructKind::Tuple || kind == StructKind::TupleStruct {
981 let fields: alloc::vec::Vec<_> = struct_.fields_for_binary_serialize().collect();
982 let is_transparent = shape.is_transparent() && fields.len() == 1;
983
984 if is_transparent {
985 let (field_item, field_value) = &fields[0];
986 self.serialize_field_value(field_item, *field_value)?;
987 } else {
988 self.serializer
989 .begin_seq()
990 .map_err(SerializeError::Backend)?;
991 for (idx, (field_item, field_value)) in fields.into_iter().enumerate() {
992 self.push(PathSegment::Index(idx));
993 self.serialize_field_value(&field_item, field_value)?;
994 self.pop();
995 }
996 self.serializer.end_seq().map_err(SerializeError::Backend)?;
997 }
998 } else {
999 self.serializer
1000 .begin_struct()
1001 .map_err(SerializeError::Backend)?;
1002
1003 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1004 struct_.fields_for_binary_serialize().collect()
1005 } else {
1006 struct_.fields_for_serialize().collect()
1007 };
1008
1009 sort_fields_if_needed(self.serializer, &mut fields);
1010
1011 for (field_item, field_value) in fields {
1012 if field_item.flattened
1014 && let Some(field) = field_item.field
1015 && let shape = field.shape()
1016 && let Some(tag_key) = shape.get_tag_attr()
1017 && shape.get_content_attr().is_none()
1018 {
1019 let variant_name = field_item.effective_name();
1020
1021 if field_mode == StructFieldMode::Named {
1022 self.serializer
1023 .field_key(tag_key)
1024 .map_err(SerializeError::Backend)?;
1025 }
1026 self.serializer
1027 .scalar(ScalarValue::Str(Cow::Borrowed(variant_name)))
1028 .map_err(SerializeError::Backend)?;
1029
1030 if let Ok(inner_struct) = field_value.into_struct() {
1031 for (inner_item, inner_value) in inner_struct.fields_for_serialize() {
1032 if field_mode == StructFieldMode::Named {
1033 self.serializer
1034 .field_key(inner_item.effective_name())
1035 .map_err(SerializeError::Backend)?;
1036 }
1037 self.push(PathSegment::Field(Cow::Owned(
1038 inner_item.effective_name().to_string(),
1039 )));
1040 self.serialize_field_value(&inner_item, inner_value)?;
1041 self.pop();
1042 }
1043 } else if let Ok(enum_peek) = field_value.into_enum() {
1044 for (inner_item, inner_value) in enum_peek.fields_for_serialize() {
1045 if field_mode == StructFieldMode::Named {
1046 self.serializer
1047 .field_key(inner_item.effective_name())
1048 .map_err(SerializeError::Backend)?;
1049 }
1050 self.push(PathSegment::Field(Cow::Owned(
1051 inner_item.effective_name().to_string(),
1052 )));
1053 self.serialize_field_value(&inner_item, inner_value)?;
1054 self.pop();
1055 }
1056 } else if matches!(field_value.shape().ty, Type::Primitive(_)) {
1057 return Err(SerializeError::Unsupported(
1058 "internally-tagged enum with scalar newtype payload cannot be \
1059 flattened; use #[facet(content = \"...\")] for adjacently-tagged \
1060 representation"
1061 .into(),
1062 ));
1063 }
1064 continue;
1065 }
1066
1067 if field_item.flattened
1071 && {
1072 let shape = field_value.shape();
1073 shape.get_tag_attr().is_none() && shape.get_content_attr().is_none()
1074 }
1075 && let Ok(enum_peek) = field_value.into_enum()
1076 {
1077 if field_mode == StructFieldMode::Named {
1078 self.serializer
1079 .field_key(field_item.effective_name())
1080 .map_err(SerializeError::Backend)?;
1081 }
1082
1083 let variant = enum_peek
1084 .active_variant()
1085 .map_err(|e| SerializeError::Unsupported(Cow::Owned(e.to_string())))?;
1086
1087 self.push(PathSegment::Variant(Cow::Owned(
1088 field_item.effective_name().to_string(),
1089 )));
1090 if variant.data.kind == StructKind::Unit {
1091 self.serializer
1092 .serialize_none()
1093 .map_err(SerializeError::Backend)?;
1094 } else {
1095 self.serialize_variant_after_tag(enum_peek, variant)?;
1096 }
1097 self.pop();
1098 continue;
1099 }
1100
1101 let key_written = self
1102 .serializer
1103 .field_metadata_with_value(&field_item, field_value)
1104 .map_err(SerializeError::Backend)?;
1105 if !key_written {
1106 self.serializer
1107 .field_metadata(&field_item)
1108 .map_err(SerializeError::Backend)?;
1109 if field_mode == StructFieldMode::Named {
1110 self.serializer
1111 .field_key(field_item.effective_name())
1112 .map_err(SerializeError::Backend)?;
1113 }
1114 }
1115 self.push(PathSegment::Field(Cow::Owned(
1116 field_item.effective_name().to_string(),
1117 )));
1118 self.serialize_field_value(&field_item, field_value)?;
1119 self.pop();
1120 }
1121 self.serializer
1122 .end_struct()
1123 .map_err(SerializeError::Backend)?;
1124 }
1125 Ok(())
1126 }
1127
1128 fn serialize_flattened_newtype_value<'mem, 'facet>(
1138 &mut self,
1139 value: Peek<'mem, 'facet>,
1140 used_tag_keys: &[&str],
1141 ) -> Result<(), SerializeError<S::Error>> {
1142 let shape = value.shape();
1143 let field_mode = self.serializer.struct_field_mode();
1144
1145 if let Ok(struct_) = value.into_struct() {
1147 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1148 struct_.fields_for_binary_serialize().collect()
1149 } else {
1150 struct_.fields_for_serialize().collect()
1151 };
1152 sort_fields_if_needed(self.serializer, &mut fields);
1153 for (field_item, field_value) in fields {
1154 self.serializer
1155 .field_metadata(&field_item)
1156 .map_err(SerializeError::Backend)?;
1157 if field_mode == StructFieldMode::Named {
1158 self.serializer
1159 .field_key(field_item.effective_name())
1160 .map_err(SerializeError::Backend)?;
1161 }
1162 self.push(PathSegment::Field(Cow::Owned(
1163 field_item.effective_name().to_string(),
1164 )));
1165 self.serialize_field_value(&field_item, field_value)?;
1166 self.pop();
1167 }
1168 return Ok(());
1169 }
1170
1171 if let Some(inner_tag) = shape.get_tag_attr()
1173 && shape.get_content_attr().is_none()
1174 && let Ok(inner_enum) = value.into_enum()
1175 {
1176 if used_tag_keys.contains(&inner_tag) {
1181 return Err(SerializeError::Unsupported(
1182 format!(
1183 "nested internally-tagged enums use the same tag key \"{}\"; \
1184 this is ambiguous when flattened into a single object",
1185 inner_tag
1186 )
1187 .into(),
1188 ));
1189 }
1190
1191 let inner_variant = inner_enum
1192 .active_variant()
1193 .map_err(|e| SerializeError::Unsupported(Cow::Owned(e.to_string())))?;
1194
1195 self.serializer
1197 .field_key(inner_tag)
1198 .map_err(SerializeError::Backend)?;
1199 self.serializer
1200 .scalar(ScalarValue::Str(Cow::Borrowed(
1201 inner_variant.effective_name(),
1202 )))
1203 .map_err(SerializeError::Backend)?;
1204
1205 self.push(PathSegment::Variant(Cow::Borrowed(
1206 inner_variant.effective_name(),
1207 )));
1208
1209 match inner_variant.data.kind {
1210 StructKind::Unit => {}
1211 StructKind::Struct => {
1212 let mut inner_fields: alloc::vec::Vec<_> =
1213 if field_mode == StructFieldMode::Unnamed {
1214 inner_enum.fields_for_binary_serialize().collect()
1215 } else {
1216 inner_enum.fields_for_serialize().collect()
1217 };
1218 sort_fields_if_needed(self.serializer, &mut inner_fields);
1219
1220 for (field_item, field_value) in inner_fields {
1221 self.serializer
1222 .field_metadata(&field_item)
1223 .map_err(SerializeError::Backend)?;
1224 if field_mode == StructFieldMode::Named {
1225 self.serializer
1226 .field_key(field_item.effective_name())
1227 .map_err(SerializeError::Backend)?;
1228 }
1229 self.push(PathSegment::Field(Cow::Owned(
1230 field_item.effective_name().to_string(),
1231 )));
1232 self.serialize_field_value(&field_item, field_value)?;
1233 self.pop();
1234 }
1235 }
1236 StructKind::TupleStruct | StructKind::Tuple => {
1237 if inner_variant.data.fields.len() != 1 {
1239 self.pop();
1240 return Err(SerializeError::Unsupported(Cow::Borrowed(
1241 "internally tagged tuple variants with multiple fields are not supported",
1242 )));
1243 }
1244 let nested_value = inner_enum
1245 .field(0)
1246 .map_err(|e| SerializeError::Unsupported(Cow::Owned(e.to_string())))?
1247 .expect("single-field tuple variant should have field 0");
1248 let mut inner_used_tag_keys = alloc::vec::Vec::from(used_tag_keys);
1249 inner_used_tag_keys.push(inner_tag);
1250 self.serialize_flattened_newtype_value(nested_value, &inner_used_tag_keys)?;
1251 }
1252 }
1253
1254 self.pop();
1255 return Ok(());
1256 }
1257
1258 Err(SerializeError::Unsupported(
1260 "internally-tagged enum with scalar newtype payload cannot be \
1261 flattened; use #[facet(content = \"...\")] for adjacently-tagged \
1262 representation"
1263 .into(),
1264 ))
1265 }
1266
1267 fn serialize_discriminant<'mem, 'facet>(
1268 &mut self,
1269 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1270 ) -> Result<(), SerializeError<S::Error>> {
1271 match enum_.ty().enum_repr {
1272 facet_core::EnumRepr::Rust => Err(SerializeError::Internal(Cow::Borrowed(
1273 "enum does not have an explicit representation",
1274 ))),
1275 facet_core::EnumRepr::RustNPO
1276 | facet_core::EnumRepr::U8
1277 | facet_core::EnumRepr::U16
1278 | facet_core::EnumRepr::U32
1279 | facet_core::EnumRepr::U64
1280 | facet_core::EnumRepr::USize => self
1281 .serializer
1282 .scalar(ScalarValue::U64(enum_.discriminant() as u64))
1283 .map_err(SerializeError::Backend),
1284 facet_core::EnumRepr::I8
1285 | facet_core::EnumRepr::I16
1286 | facet_core::EnumRepr::I32
1287 | facet_core::EnumRepr::I64
1288 | facet_core::EnumRepr::ISize => self
1289 .serializer
1290 .scalar(ScalarValue::I64(enum_.discriminant()))
1291 .map_err(SerializeError::Backend),
1292 }
1293 }
1294
1295 fn serialize_enum<'mem, 'facet>(
1296 &mut self,
1297 shape: &'static Shape,
1298 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1299 ) -> Result<(), SerializeError<S::Error>> {
1300 let variant = enum_.active_variant().map_err(|_| {
1301 SerializeError::Unsupported(Cow::Borrowed("opaque enum layout is unsupported"))
1302 })?;
1303
1304 self.serializer
1305 .variant_metadata(variant)
1306 .map_err(SerializeError::Backend)?;
1307
1308 if shape.is_cow() {
1310 let inner = enum_
1311 .field(0)
1312 .map_err(|_| {
1313 SerializeError::Internal(Cow::Borrowed("cow variant field lookup failed"))
1314 })?
1315 .ok_or(SerializeError::Internal(Cow::Borrowed(
1316 "cow variant has no field",
1317 )))?;
1318 return self.serialize_impl(inner);
1319 }
1320
1321 if self.serializer.enum_variant_encoding() == EnumVariantEncoding::Index {
1322 let variant_index = enum_.variant_index().map_err(|_| {
1323 SerializeError::Unsupported(Cow::Borrowed("opaque enum layout is unsupported"))
1324 })?;
1325 self.serializer
1326 .begin_enum_variant(variant_index, variant.name)
1327 .map_err(SerializeError::Backend)?;
1328
1329 self.push(PathSegment::Variant(Cow::Borrowed(variant.name)));
1330 let result = match variant.data.kind {
1331 StructKind::Unit => Ok(()),
1332 StructKind::TupleStruct | StructKind::Tuple | StructKind::Struct => {
1333 for (idx, (field_item, field_value)) in
1334 enum_.fields_for_binary_serialize().enumerate()
1335 {
1336 self.push(PathSegment::Index(idx));
1337 self.serialize_field_value(&field_item, field_value)?;
1338 self.pop();
1339 }
1340 Ok(())
1341 }
1342 };
1343 self.pop();
1344 return result;
1345 }
1346
1347 let numeric = shape.is_numeric();
1348 let untagged = shape.is_untagged();
1349 let tag = shape.get_tag_attr();
1350 let content = shape.get_content_attr();
1351
1352 if numeric && tag.is_none() {
1353 return serialize_numeric_enum(self.serializer, variant);
1354 }
1355 if untagged {
1356 self.push(PathSegment::Variant(Cow::Borrowed(
1357 variant.effective_name(),
1358 )));
1359 let result = self.serialize_untagged_enum(enum_, variant);
1360 self.pop();
1361 return result;
1362 }
1363
1364 if variant.is_other() {
1368 let has_tag_field = variant.data.fields.iter().any(|f| f.is_variant_tag());
1369 if !has_tag_field {
1370 self.push(PathSegment::Variant(Cow::Borrowed(
1371 variant.effective_name(),
1372 )));
1373 let result = self.serialize_untagged_enum(enum_, variant);
1374 self.pop();
1375 return result;
1376 }
1377 }
1378
1379 match (tag, content) {
1380 (Some(tag_key), None) => {
1381 self.serializer
1383 .begin_struct()
1384 .map_err(SerializeError::Backend)?;
1385 self.serializer
1386 .field_key(tag_key)
1387 .map_err(SerializeError::Backend)?;
1388
1389 if numeric {
1390 self.serialize_discriminant(enum_)?;
1391 } else {
1392 self.serializer
1393 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1394 .map_err(SerializeError::Backend)?;
1395 }
1396
1397 self.push(PathSegment::Variant(Cow::Borrowed(
1398 variant.effective_name(),
1399 )));
1400 let field_mode = self.serializer.struct_field_mode();
1401 match variant.data.kind {
1402 StructKind::Unit => {}
1403 StructKind::Struct => {
1404 let mut fields: alloc::vec::Vec<_> =
1405 if field_mode == StructFieldMode::Unnamed {
1406 enum_.fields_for_binary_serialize().collect()
1407 } else {
1408 enum_.fields_for_serialize().collect()
1409 };
1410 sort_fields_if_needed(self.serializer, &mut fields);
1411 for (field_item, field_value) in fields {
1412 self.serializer
1413 .field_metadata(&field_item)
1414 .map_err(SerializeError::Backend)?;
1415 if field_mode == StructFieldMode::Named {
1416 self.serializer
1417 .field_key(field_item.effective_name())
1418 .map_err(SerializeError::Backend)?;
1419 }
1420 self.push(PathSegment::Field(Cow::Owned(
1421 field_item.effective_name().to_string(),
1422 )));
1423 self.serialize_field_value(&field_item, field_value)?;
1424 self.pop();
1425 }
1426 }
1427 StructKind::TupleStruct | StructKind::Tuple => {
1428 if variant.data.fields.len() != 1 {
1433 self.pop();
1434 return Err(SerializeError::Unsupported(Cow::Borrowed(
1435 "internally tagged tuple variants with multiple fields are not supported",
1436 )));
1437 }
1438
1439 let inner_value = enum_
1440 .field(0)
1441 .map_err(|e| SerializeError::Unsupported(Cow::Owned(e.to_string())))?
1442 .expect("single-field tuple variant should have field 0");
1443
1444 self.serialize_flattened_newtype_value(inner_value, &[tag_key])?;
1445 }
1446 }
1447 self.pop();
1448
1449 self.serializer
1450 .end_struct()
1451 .map_err(SerializeError::Backend)?;
1452 return Ok(());
1453 }
1454 (Some(tag_key), Some(content_key)) => {
1455 return self.serialize_adjacently_tagged_enum(
1457 enum_,
1458 variant,
1459 tag_key,
1460 content_key,
1461 numeric,
1462 );
1463 }
1464 (None, Some(_)) => {
1465 return Err(SerializeError::Unsupported(Cow::Borrowed(
1466 "adjacent content key set without tag key",
1467 )));
1468 }
1469 (None, None) => {}
1470 }
1471
1472 self.serialize_externally_tagged_enum(enum_, variant)
1474 }
1475
1476 fn serialize_adjacently_tagged_enum<'mem, 'facet>(
1477 &mut self,
1478 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1479 variant: &'static facet_core::Variant,
1480 tag_key: &'static str,
1481 content_key: &'static str,
1482 numeric: bool,
1483 ) -> Result<(), SerializeError<S::Error>> {
1484 let field_mode = self.serializer.struct_field_mode();
1485 self.serializer
1486 .begin_struct()
1487 .map_err(SerializeError::Backend)?;
1488 self.serializer
1489 .field_key(tag_key)
1490 .map_err(SerializeError::Backend)?;
1491
1492 if numeric {
1493 self.serialize_discriminant(enum_)?;
1494 } else {
1495 self.serializer
1496 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1497 .map_err(SerializeError::Backend)?;
1498 }
1499
1500 self.push(PathSegment::Variant(Cow::Borrowed(
1501 variant.effective_name(),
1502 )));
1503
1504 match variant.data.kind {
1505 StructKind::Unit => {}
1506 StructKind::Struct => {
1507 self.serializer
1508 .field_key(content_key)
1509 .map_err(SerializeError::Backend)?;
1510 self.serializer
1511 .begin_struct()
1512 .map_err(SerializeError::Backend)?;
1513 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1514 enum_.fields_for_binary_serialize().collect()
1515 } else {
1516 enum_.fields_for_serialize().collect()
1517 };
1518 sort_fields_if_needed(self.serializer, &mut fields);
1519 for (field_item, field_value) in fields {
1520 self.serializer
1521 .field_metadata(&field_item)
1522 .map_err(SerializeError::Backend)?;
1523 if field_mode == StructFieldMode::Named {
1524 self.serializer
1525 .field_key(field_item.effective_name())
1526 .map_err(SerializeError::Backend)?;
1527 }
1528 self.push(PathSegment::Field(Cow::Owned(
1529 field_item.effective_name().to_string(),
1530 )));
1531 self.serialize_field_value(&field_item, field_value)?;
1532 self.pop();
1533 }
1534 self.serializer
1535 .end_struct()
1536 .map_err(SerializeError::Backend)?;
1537 }
1538 StructKind::TupleStruct | StructKind::Tuple => {
1539 self.serializer
1540 .field_key(content_key)
1541 .map_err(SerializeError::Backend)?;
1542
1543 let field_count = variant.data.fields.len();
1544 if field_count == 1 {
1545 let inner = enum_
1546 .field(0)
1547 .map_err(|_| {
1548 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1549 })?
1550 .ok_or(SerializeError::Internal(Cow::Borrowed(
1551 "variant reported 1 field but field(0) returned None",
1552 )))?;
1553 let field_def = variant.data.fields.first().copied();
1554 self.with_field_context(field_def, |this| this.serialize_impl(inner))?;
1555 } else {
1556 self.serializer
1557 .begin_seq()
1558 .map_err(SerializeError::Backend)?;
1559 for idx in 0..field_count {
1560 let inner = enum_
1561 .field(idx)
1562 .map_err(|_| {
1563 SerializeError::Internal(Cow::Borrowed(
1564 "variant field lookup failed",
1565 ))
1566 })?
1567 .ok_or(SerializeError::Internal(Cow::Borrowed(
1568 "variant field missing while iterating tuple fields",
1569 )))?;
1570 self.push(PathSegment::Index(idx));
1571 let field_def = variant.data.fields.get(idx).copied();
1572 self.with_field_context(field_def, |this| this.serialize_impl(inner))?;
1573 self.pop();
1574 }
1575 self.serializer.end_seq().map_err(SerializeError::Backend)?;
1576 }
1577 }
1578 }
1579
1580 self.pop();
1581 self.serializer
1582 .end_struct()
1583 .map_err(SerializeError::Backend)?;
1584 Ok(())
1585 }
1586
1587 fn serialize_externally_tagged_enum<'mem, 'facet>(
1588 &mut self,
1589 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1590 variant: &'static facet_core::Variant,
1591 ) -> Result<(), SerializeError<S::Error>> {
1592 let field_mode = self.serializer.struct_field_mode();
1593
1594 let tag_name: Cow<'_, str> = if variant.is_other() {
1597 let mut tag_value: Option<Cow<'_, str>> = None;
1598 let fields_iter: alloc::boxed::Box<
1599 dyn Iterator<Item = (facet_reflect::FieldItem, facet_reflect::Peek<'_, '_>)>,
1600 > = if field_mode == StructFieldMode::Unnamed {
1601 alloc::boxed::Box::new(enum_.fields_for_binary_serialize())
1602 } else {
1603 alloc::boxed::Box::new(enum_.fields_for_serialize())
1604 };
1605 for (field_item, field_value) in fields_iter {
1606 if let Some(field) = field_item.field
1607 && field.is_variant_tag()
1608 {
1609 if let Ok(opt) = field_value.into_option()
1610 && let Some(inner) = opt.value()
1611 && let Some(s) = inner.as_str()
1612 {
1613 tag_value = Some(Cow::Borrowed(s));
1614 }
1615 break;
1616 }
1617 }
1618 tag_value.unwrap_or_else(|| Cow::Borrowed(variant.effective_name()))
1619 } else {
1620 Cow::Borrowed(variant.effective_name())
1621 };
1622
1623 let use_tag_syntax = self
1625 .serializer
1626 .write_variant_tag(&tag_name)
1627 .map_err(SerializeError::Backend)?;
1628
1629 self.push(PathSegment::Variant(Cow::Owned(tag_name.to_string())));
1630
1631 let result = if use_tag_syntax {
1632 self.serialize_variant_after_tag(enum_, variant)
1633 } else {
1634 self.serialize_standard_externally_tagged(enum_, variant)
1635 };
1636
1637 self.pop();
1638 result
1639 }
1640
1641 fn serialize_variant_after_tag<'mem, 'facet>(
1642 &mut self,
1643 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1644 variant: &'static facet_core::Variant,
1645 ) -> Result<(), SerializeError<S::Error>> {
1646 let field_mode = self.serializer.struct_field_mode();
1647
1648 match variant.data.kind {
1649 StructKind::Unit => {
1650 self.serializer
1651 .finish_variant_tag_unit_payload()
1652 .map_err(SerializeError::Backend)?;
1653 Ok(())
1654 }
1655 StructKind::TupleStruct | StructKind::Tuple => {
1656 let field_count = variant.data.fields.len();
1657 if field_count == 1 {
1658 let inner = enum_
1659 .field(0)
1660 .map_err(|_| {
1661 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1662 })?
1663 .ok_or(SerializeError::Internal(Cow::Borrowed(
1664 "variant reported 1 field but field(0) returned None",
1665 )))?;
1666 if let Some(field_def) = variant.data.fields.first().copied()
1667 && let Some(proxy_def) =
1668 field_def.effective_proxy(self.serializer.format_namespace())
1669 {
1670 self.with_field_context(Some(field_def), |this| {
1671 this.serialize_via_proxy(inner, proxy_def)
1672 })?;
1673 } else {
1674 self.with_field_context(variant.data.fields.first().copied(), |this| {
1675 this.serialize_impl(inner)
1676 })?;
1677 }
1678 } else {
1679 self.serializer
1680 .begin_seq_after_tag()
1681 .map_err(SerializeError::Backend)?;
1682 for idx in 0..field_count {
1683 let inner = enum_
1684 .field(idx)
1685 .map_err(|_| {
1686 SerializeError::Internal(Cow::Borrowed(
1687 "variant field lookup failed",
1688 ))
1689 })?
1690 .ok_or(SerializeError::Internal(Cow::Borrowed(
1691 "variant field missing while iterating tuple fields",
1692 )))?;
1693 self.push(PathSegment::Index(idx));
1694 if let Some(field_def) = variant.data.fields.get(idx).copied()
1695 && let Some(proxy_def) =
1696 field_def.effective_proxy(self.serializer.format_namespace())
1697 {
1698 self.with_field_context(Some(field_def), |this| {
1699 this.serialize_via_proxy(inner, proxy_def)
1700 })?;
1701 } else {
1702 self.with_field_context(
1703 variant.data.fields.get(idx).copied(),
1704 |this| this.serialize_impl(inner),
1705 )?;
1706 }
1707 self.pop();
1708 }
1709 self.serializer.end_seq().map_err(SerializeError::Backend)?;
1710 }
1711 Ok(())
1712 }
1713 StructKind::Struct => {
1714 let is_other = variant.is_other();
1715 let fields_iter: alloc::boxed::Box<
1716 dyn Iterator<Item = (facet_reflect::FieldItem, facet_reflect::Peek<'_, '_>)>,
1717 > = if field_mode == StructFieldMode::Unnamed {
1718 alloc::boxed::Box::new(enum_.fields_for_binary_serialize())
1719 } else {
1720 alloc::boxed::Box::new(enum_.fields_for_serialize())
1721 };
1722 let mut fields: alloc::vec::Vec<_> = fields_iter
1723 .filter(|(field_item, _)| {
1724 if is_other {
1725 field_item
1726 .field
1727 .map(|f| f.metadata_kind().is_none() && !f.is_variant_tag())
1728 .unwrap_or(true)
1729 } else {
1730 true
1731 }
1732 })
1733 .collect();
1734
1735 if fields.is_empty() {
1736 self.serializer
1737 .finish_variant_tag_unit_payload()
1738 .map_err(SerializeError::Backend)?;
1739 return Ok(());
1740 }
1741
1742 self.serializer
1743 .begin_struct_after_tag()
1744 .map_err(SerializeError::Backend)?;
1745 sort_fields_if_needed(self.serializer, &mut fields);
1746 for (field_item, field_value) in fields {
1747 self.serializer
1748 .field_metadata(&field_item)
1749 .map_err(SerializeError::Backend)?;
1750 if field_mode == StructFieldMode::Named {
1751 self.serializer
1752 .field_key(field_item.effective_name())
1753 .map_err(SerializeError::Backend)?;
1754 }
1755 self.push(PathSegment::Field(Cow::Owned(
1756 field_item.effective_name().to_string(),
1757 )));
1758 self.serialize_field_value(&field_item, field_value)?;
1759 self.pop();
1760 }
1761 self.serializer
1762 .end_struct()
1763 .map_err(SerializeError::Backend)?;
1764 Ok(())
1765 }
1766 }
1767 }
1768
1769 fn serialize_standard_externally_tagged<'mem, 'facet>(
1770 &mut self,
1771 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1772 variant: &'static facet_core::Variant,
1773 ) -> Result<(), SerializeError<S::Error>> {
1774 let field_mode = self.serializer.struct_field_mode();
1775
1776 match variant.data.kind {
1777 StructKind::Unit => {
1778 self.serializer
1779 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1780 .map_err(SerializeError::Backend)?;
1781 Ok(())
1782 }
1783 StructKind::TupleStruct | StructKind::Tuple => {
1784 self.serializer
1785 .begin_struct()
1786 .map_err(SerializeError::Backend)?;
1787 self.serializer
1788 .field_key(variant.effective_name())
1789 .map_err(SerializeError::Backend)?;
1790
1791 let field_count = variant.data.fields.len();
1792 if field_count == 1 {
1793 let inner = enum_
1794 .field(0)
1795 .map_err(|_| {
1796 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1797 })?
1798 .ok_or(SerializeError::Internal(Cow::Borrowed(
1799 "variant reported 1 field but field(0) returned None",
1800 )))?;
1801 if let Some(field_def) = variant.data.fields.first().copied()
1802 && let Some(proxy_def) =
1803 field_def.effective_proxy(self.serializer.format_namespace())
1804 {
1805 self.with_field_context(Some(field_def), |this| {
1806 this.serialize_via_proxy(inner, proxy_def)
1807 })?;
1808 } else {
1809 self.with_field_context(variant.data.fields.first().copied(), |this| {
1810 this.serialize_impl(inner)
1811 })?;
1812 }
1813 } else {
1814 self.serializer
1815 .begin_seq()
1816 .map_err(SerializeError::Backend)?;
1817 for idx in 0..field_count {
1818 let inner = enum_
1819 .field(idx)
1820 .map_err(|_| {
1821 SerializeError::Internal(Cow::Borrowed(
1822 "variant field lookup failed",
1823 ))
1824 })?
1825 .ok_or(SerializeError::Internal(Cow::Borrowed(
1826 "variant field missing while iterating tuple fields",
1827 )))?;
1828 self.push(PathSegment::Index(idx));
1829 if let Some(field_def) = variant.data.fields.get(idx).copied()
1830 && let Some(proxy_def) =
1831 field_def.effective_proxy(self.serializer.format_namespace())
1832 {
1833 self.with_field_context(Some(field_def), |this| {
1834 this.serialize_via_proxy(inner, proxy_def)
1835 })?;
1836 } else {
1837 self.with_field_context(
1838 variant.data.fields.get(idx).copied(),
1839 |this| this.serialize_impl(inner),
1840 )?;
1841 }
1842 self.pop();
1843 }
1844 self.serializer.end_seq().map_err(SerializeError::Backend)?;
1845 }
1846
1847 self.serializer
1848 .end_struct()
1849 .map_err(SerializeError::Backend)?;
1850 Ok(())
1851 }
1852 StructKind::Struct => {
1853 self.serializer
1854 .begin_struct()
1855 .map_err(SerializeError::Backend)?;
1856 self.serializer
1857 .field_key(variant.effective_name())
1858 .map_err(SerializeError::Backend)?;
1859
1860 self.serializer
1861 .begin_struct()
1862 .map_err(SerializeError::Backend)?;
1863 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1864 enum_.fields_for_binary_serialize().collect()
1865 } else {
1866 enum_.fields_for_serialize().collect()
1867 };
1868 sort_fields_if_needed(self.serializer, &mut fields);
1869 for (field_item, field_value) in fields {
1870 self.serializer
1871 .field_metadata(&field_item)
1872 .map_err(SerializeError::Backend)?;
1873 if field_mode == StructFieldMode::Named {
1874 self.serializer
1875 .field_key(field_item.effective_name())
1876 .map_err(SerializeError::Backend)?;
1877 }
1878 self.push(PathSegment::Field(Cow::Owned(
1879 field_item.effective_name().to_string(),
1880 )));
1881 self.serialize_field_value(&field_item, field_value)?;
1882 self.pop();
1883 }
1884 self.serializer
1885 .end_struct()
1886 .map_err(SerializeError::Backend)?;
1887
1888 self.serializer
1889 .end_struct()
1890 .map_err(SerializeError::Backend)?;
1891 Ok(())
1892 }
1893 }
1894 }
1895
1896 fn serialize_untagged_enum<'mem, 'facet>(
1897 &mut self,
1898 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1899 variant: &'static facet_core::Variant,
1900 ) -> Result<(), SerializeError<S::Error>> {
1901 let field_mode = self.serializer.struct_field_mode();
1902
1903 match variant.data.kind {
1904 StructKind::Unit => self
1905 .serializer
1906 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1907 .map_err(SerializeError::Backend),
1908 StructKind::TupleStruct | StructKind::Tuple => {
1909 let field_count = variant.data.fields.len();
1910 if field_count == 1 {
1911 let inner = enum_
1912 .field(0)
1913 .map_err(|_| {
1914 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1915 })?
1916 .ok_or(SerializeError::Internal(Cow::Borrowed(
1917 "variant reported 1 field but field(0) returned None",
1918 )))?;
1919 let field_def = variant.data.fields.first().copied();
1920 self.with_field_context(field_def, |this| this.serialize_impl(inner))
1921 } else {
1922 self.serializer
1923 .begin_seq()
1924 .map_err(SerializeError::Backend)?;
1925 for idx in 0..field_count {
1926 let inner = enum_
1927 .field(idx)
1928 .map_err(|_| {
1929 SerializeError::Internal(Cow::Borrowed(
1930 "variant field lookup failed",
1931 ))
1932 })?
1933 .ok_or(SerializeError::Internal(Cow::Borrowed(
1934 "variant field missing while iterating tuple fields",
1935 )))?;
1936 self.push(PathSegment::Index(idx));
1937 let field_def = variant.data.fields.get(idx).copied();
1938 self.with_field_context(field_def, |this| this.serialize_impl(inner))?;
1939 self.pop();
1940 }
1941 self.serializer.end_seq().map_err(SerializeError::Backend)?;
1942 Ok(())
1943 }
1944 }
1945 StructKind::Struct => {
1946 self.serializer
1947 .begin_struct()
1948 .map_err(SerializeError::Backend)?;
1949 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1950 enum_.fields_for_binary_serialize().collect()
1951 } else {
1952 enum_.fields_for_serialize().collect()
1953 };
1954 sort_fields_if_needed(self.serializer, &mut fields);
1955 for (field_item, field_value) in fields {
1956 self.serializer
1957 .field_metadata(&field_item)
1958 .map_err(SerializeError::Backend)?;
1959 if field_mode == StructFieldMode::Named {
1960 self.serializer
1961 .field_key(field_item.effective_name())
1962 .map_err(SerializeError::Backend)?;
1963 }
1964 self.push(PathSegment::Field(Cow::Owned(
1965 field_item.effective_name().to_string(),
1966 )));
1967 self.serialize_field_value(&field_item, field_value)?;
1968 self.pop();
1969 }
1970 self.serializer
1971 .end_struct()
1972 .map_err(SerializeError::Backend)?;
1973 Ok(())
1974 }
1975 }
1976 }
1977
1978 fn serialize_dynamic_value<'mem, 'facet>(
1979 &mut self,
1980 dynamic: facet_reflect::PeekDynamicValue<'mem, 'facet>,
1981 ) -> Result<(), SerializeError<S::Error>> {
1982 let tagged = self.serializer.dynamic_value_encoding() == DynamicValueEncoding::Tagged;
1983
1984 match dynamic.kind() {
1985 DynValueKind::Null => {
1986 if tagged {
1987 self.serializer
1988 .dynamic_value_tag(DynamicValueTag::Null)
1989 .map_err(SerializeError::Backend)?;
1990 }
1991 self.serializer
1992 .scalar(ScalarValue::Null)
1993 .map_err(SerializeError::Backend)
1994 }
1995 DynValueKind::Bool => {
1996 let value = dynamic.as_bool().ok_or_else(|| {
1997 SerializeError::Internal(Cow::Borrowed("dynamic bool missing value"))
1998 })?;
1999 if tagged {
2000 self.serializer
2001 .dynamic_value_tag(DynamicValueTag::Bool)
2002 .map_err(SerializeError::Backend)?;
2003 }
2004 self.serializer
2005 .scalar(ScalarValue::Bool(value))
2006 .map_err(SerializeError::Backend)
2007 }
2008 DynValueKind::Number => {
2009 if let Some(n) = dynamic.as_i64() {
2010 if tagged {
2011 self.serializer
2012 .dynamic_value_tag(DynamicValueTag::I64)
2013 .map_err(SerializeError::Backend)?;
2014 }
2015 self.serializer
2016 .scalar(ScalarValue::I64(n))
2017 .map_err(SerializeError::Backend)
2018 } else if let Some(n) = dynamic.as_u64() {
2019 if tagged {
2020 self.serializer
2021 .dynamic_value_tag(DynamicValueTag::U64)
2022 .map_err(SerializeError::Backend)?;
2023 }
2024 self.serializer
2025 .scalar(ScalarValue::U64(n))
2026 .map_err(SerializeError::Backend)
2027 } else if let Some(n) = dynamic.as_f64() {
2028 if tagged {
2029 self.serializer
2030 .dynamic_value_tag(DynamicValueTag::F64)
2031 .map_err(SerializeError::Backend)?;
2032 }
2033 self.serializer
2034 .scalar(ScalarValue::F64(n))
2035 .map_err(SerializeError::Backend)
2036 } else {
2037 Err(SerializeError::Unsupported(Cow::Borrowed(
2038 "dynamic number not representable",
2039 )))
2040 }
2041 }
2042 DynValueKind::String => {
2043 let value = dynamic.as_str().ok_or_else(|| {
2044 SerializeError::Internal(Cow::Borrowed("dynamic string missing value"))
2045 })?;
2046 if tagged {
2047 self.serializer
2048 .dynamic_value_tag(DynamicValueTag::String)
2049 .map_err(SerializeError::Backend)?;
2050 }
2051 self.serializer
2052 .scalar(ScalarValue::Str(Cow::Borrowed(value)))
2053 .map_err(SerializeError::Backend)
2054 }
2055 DynValueKind::Bytes => {
2056 let value = dynamic.as_bytes().ok_or_else(|| {
2057 SerializeError::Internal(Cow::Borrowed("dynamic bytes missing value"))
2058 })?;
2059 if tagged {
2060 self.serializer
2061 .dynamic_value_tag(DynamicValueTag::Bytes)
2062 .map_err(SerializeError::Backend)?;
2063 }
2064 self.serializer
2065 .scalar(ScalarValue::Bytes(Cow::Borrowed(value)))
2066 .map_err(SerializeError::Backend)
2067 }
2068 DynValueKind::Array => {
2069 let len = dynamic.array_len().ok_or_else(|| {
2070 SerializeError::Internal(Cow::Borrowed("dynamic array missing length"))
2071 })?;
2072 if tagged {
2073 self.serializer
2074 .dynamic_value_tag(DynamicValueTag::Array)
2075 .map_err(SerializeError::Backend)?;
2076 }
2077 self.serializer
2078 .begin_seq_with_len(len)
2079 .map_err(SerializeError::Backend)?;
2080 if let Some(iter) = dynamic.array_iter() {
2081 for (idx, item) in iter.enumerate() {
2082 self.push(PathSegment::Index(idx));
2083 self.serialize_impl(item)?;
2084 self.pop();
2085 }
2086 }
2087 self.serializer.end_seq().map_err(SerializeError::Backend)
2088 }
2089 DynValueKind::Object => {
2090 let len = dynamic.object_len().ok_or_else(|| {
2091 SerializeError::Internal(Cow::Borrowed("dynamic object missing length"))
2092 })?;
2093 if tagged {
2094 self.serializer
2095 .dynamic_value_tag(DynamicValueTag::Object)
2096 .map_err(SerializeError::Backend)?;
2097 }
2098 match self.serializer.map_encoding() {
2099 MapEncoding::Pairs => {
2100 self.serializer
2101 .begin_map_with_len(len)
2102 .map_err(SerializeError::Backend)?;
2103 if let Some(iter) = dynamic.object_iter() {
2104 for (key, value) in iter {
2105 self.serializer
2106 .scalar(ScalarValue::Str(Cow::Borrowed(key)))
2107 .map_err(SerializeError::Backend)?;
2108 self.push(PathSegment::Field(Cow::Owned(key.to_string())));
2109 self.serialize_impl(value)?;
2110 self.pop();
2111 }
2112 }
2113 self.serializer.end_map().map_err(SerializeError::Backend)
2114 }
2115 MapEncoding::Struct => {
2116 self.serializer
2117 .begin_struct()
2118 .map_err(SerializeError::Backend)?;
2119 if let Some(iter) = dynamic.object_iter() {
2120 for (key, value) in iter {
2121 self.serializer
2122 .field_key(key)
2123 .map_err(SerializeError::Backend)?;
2124 self.push(PathSegment::Field(Cow::Owned(key.to_string())));
2125 self.serialize_impl(value)?;
2126 self.pop();
2127 }
2128 }
2129 self.serializer
2130 .end_struct()
2131 .map_err(SerializeError::Backend)
2132 }
2133 }
2134 }
2135 DynValueKind::DateTime => {
2136 let dt = dynamic.as_datetime().ok_or_else(|| {
2137 SerializeError::Internal(Cow::Borrowed("dynamic datetime missing value"))
2138 })?;
2139 if tagged {
2140 self.serializer
2141 .dynamic_value_tag(DynamicValueTag::DateTime)
2142 .map_err(SerializeError::Backend)?;
2143 }
2144 let s = format_dyn_datetime(dt);
2145 self.serializer
2146 .scalar(ScalarValue::Str(Cow::Owned(s)))
2147 .map_err(SerializeError::Backend)
2148 }
2149 DynValueKind::QName | DynValueKind::Uuid => Err(SerializeError::Unsupported(
2150 Cow::Borrowed("dynamic QName/Uuid serialization is not supported"),
2151 )),
2152 }
2153 }
2154
2155 #[allow(unsafe_code)]
2156 fn serialize_via_proxy<'mem, 'facet>(
2157 &mut self,
2158 value: Peek<'mem, 'facet>,
2159 proxy_def: &'static facet_core::ProxyDef,
2160 ) -> Result<(), SerializeError<S::Error>> {
2161 let proxy_shape = proxy_def.shape;
2162 let proxy_layout = proxy_shape.layout.sized_layout().map_err(|_| {
2163 SerializeError::Unsupported(Cow::Borrowed("proxy type must be sized for serialization"))
2164 })?;
2165
2166 let proxy_uninit = facet_core::alloc_for_layout(proxy_layout);
2167 let convert_result = unsafe { (proxy_def.convert_out)(value.data(), proxy_uninit) };
2168
2169 let proxy_ptr = match convert_result {
2170 Ok(ptr) => ptr,
2171 Err(msg) => {
2172 unsafe { facet_core::dealloc_for_layout(proxy_uninit.assume_init(), proxy_layout) };
2173 return Err(SerializeError::Unsupported(Cow::Owned(msg)));
2174 }
2175 };
2176
2177 let proxy_peek = unsafe { Peek::unchecked_new(proxy_ptr.as_const(), proxy_shape) };
2178 let result = self.serialize_impl(proxy_peek);
2179
2180 unsafe {
2181 let _ = proxy_shape.call_drop_in_place(proxy_ptr);
2182 facet_core::dealloc_for_layout(proxy_ptr, proxy_layout);
2183 }
2184
2185 result
2186 }
2187}
2188
2189impl<E: Debug> std::error::Error for SerializeError<E> {}
2190
2191fn def_kind_name(def: &Def) -> &'static str {
2193 match def {
2194 Def::Undefined => "Undefined",
2195 Def::Scalar => "Scalar",
2196 Def::Map(_) => "Map",
2197 Def::Set(_) => "Set",
2198 Def::List(_) => "List",
2199 Def::Array(_) => "Array",
2200 Def::NdArray(_) => "NdArray",
2201 Def::Slice(_) => "Slice",
2202 Def::Option(_) => "Option",
2203 Def::Result(_) => "Result",
2204 Def::DynamicValue(_) => "DynamicValue",
2205 Def::Pointer(_) => "Pointer",
2206 _ => "Unknown",
2207 }
2208}
2209
2210pub fn serialize_root<'mem, 'facet, S>(
2212 serializer: &mut S,
2213 value: Peek<'mem, 'facet>,
2214) -> Result<(), SerializeError<S::Error>>
2215where
2216 S: FormatSerializer,
2217{
2218 let mut ctx = SerializeContext::new(serializer);
2219 ctx.serialize(value)
2220}
2221
2222fn sort_fields_if_needed<'mem, 'facet, S>(
2224 _serializer: &S,
2225 _fields: &mut alloc::vec::Vec<(facet_reflect::FieldItem, Peek<'mem, 'facet>)>,
2226) where
2227 S: FormatSerializer,
2228{
2229 }
2231
2232fn format_dyn_datetime(
2233 (year, month, day, hour, minute, second, nanos, kind): (
2234 i32,
2235 u8,
2236 u8,
2237 u8,
2238 u8,
2239 u8,
2240 u32,
2241 DynDateTimeKind,
2242 ),
2243) -> String {
2244 let mut out = String::new();
2245 match kind {
2246 DynDateTimeKind::Offset { offset_minutes } => {
2247 let _ = write!(
2248 out,
2249 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}",
2250 year, month, day, hour, minute, second
2251 );
2252 if nanos > 0 {
2253 let _ = write!(out, ".{:09}", nanos);
2254 }
2255 if offset_minutes == 0 {
2256 out.push('Z');
2257 } else {
2258 let sign = if offset_minutes >= 0 { '+' } else { '-' };
2259 let abs = offset_minutes.unsigned_abs();
2260 let _ = write!(out, "{}{:02}:{:02}", sign, abs / 60, abs % 60);
2261 }
2262 }
2263 DynDateTimeKind::LocalDateTime => {
2264 let _ = write!(
2265 out,
2266 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}",
2267 year, month, day, hour, minute, second
2268 );
2269 if nanos > 0 {
2270 let _ = write!(out, ".{:09}", nanos);
2271 }
2272 }
2273 DynDateTimeKind::LocalDate => {
2274 let _ = write!(out, "{:04}-{:02}-{:02}", year, month, day);
2275 }
2276 DynDateTimeKind::LocalTime => {
2277 let _ = write!(out, "{:02}:{:02}:{:02}", hour, minute, second);
2278 if nanos > 0 {
2279 let _ = write!(out, ".{:09}", nanos);
2280 }
2281 }
2282 }
2283 out
2284}
2285
2286fn serialize_numeric_enum<S>(
2287 serializer: &mut S,
2288 variant: &'static facet_core::Variant,
2289) -> Result<(), SerializeError<S::Error>>
2290where
2291 S: FormatSerializer,
2292{
2293 let discriminant = variant
2294 .discriminant
2295 .ok_or(SerializeError::Unsupported(Cow::Borrowed(
2296 "Enum without a discriminant",
2297 )))?;
2298 serializer
2299 .scalar(ScalarValue::I64(discriminant))
2300 .map_err(SerializeError::Backend)
2301}
2302
2303fn deref_if_pointer<'mem, 'facet>(peek: Peek<'mem, 'facet>) -> Peek<'mem, 'facet> {
2305 if let Ok(ptr) = peek.into_pointer()
2306 && let Some(target) = ptr.borrow_inner()
2307 {
2308 return deref_if_pointer(target);
2309 }
2310 peek
2311}
2312
2313pub fn serialize_value_with_shape<S>(
2339 serializer: &mut S,
2340 value: Peek<'_, '_>,
2341 target_shape: &'static Shape,
2342) -> Result<(), SerializeError<S::Error>>
2343where
2344 S: FormatSerializer,
2345{
2346 let dynamic = value.into_dynamic_value().map_err(|_| {
2347 SerializeError::Unsupported(Cow::Borrowed(
2348 "serialize_value_with_shape requires a DynamicValue type",
2349 ))
2350 })?;
2351
2352 serialize_dynamic_with_shape(serializer, dynamic, target_shape, value.shape())
2353}
2354
2355fn serialize_dynamic_with_shape<S>(
2356 serializer: &mut S,
2357 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2358 target_shape: &'static Shape,
2359 value_shape: &'static Shape,
2360) -> Result<(), SerializeError<S::Error>>
2361where
2362 S: FormatSerializer,
2363{
2364 use facet_core::{ListDef, OptionDef, ScalarType as CoreScalarType, Type, UserType};
2365
2366 if let Def::Pointer(ptr_def) = target_shape.def
2368 && let Some(pointee) = ptr_def.pointee
2369 {
2370 return serialize_dynamic_with_shape(serializer, dynamic, pointee, value_shape);
2371 }
2372
2373 if let Some(inner_shape) = target_shape.inner {
2375 if !matches!(
2377 target_shape.def,
2378 Def::List(_) | Def::Map(_) | Def::Set(_) | Def::Array(_)
2379 ) {
2380 return serialize_dynamic_with_shape(serializer, dynamic, inner_shape, value_shape);
2381 }
2382 }
2383
2384 if let Def::Option(OptionDef { t: inner_shape, .. }) = target_shape.def {
2386 return serialize_option_from_dynamic(serializer, dynamic, inner_shape, value_shape);
2387 }
2388
2389 if let Def::List(ListDef { t: item_shape, .. }) = target_shape.def {
2391 return serialize_list_from_dynamic(serializer, dynamic, item_shape, value_shape);
2392 }
2393
2394 if let Def::Array(array_def) = target_shape.def {
2396 return serialize_array_from_dynamic(serializer, dynamic, array_def.t, value_shape);
2397 }
2398
2399 if let Def::Map(map_def) = target_shape.def {
2401 return serialize_map_from_dynamic(serializer, dynamic, map_def.k, map_def.v, value_shape);
2402 }
2403
2404 if let Some(scalar_type) = CoreScalarType::try_from_shape(target_shape) {
2406 return serialize_scalar_from_dynamic(serializer, dynamic, scalar_type);
2407 }
2408
2409 match target_shape.ty {
2411 Type::User(UserType::Struct(struct_def)) => {
2412 serialize_struct_from_dynamic(serializer, dynamic, struct_def, value_shape)
2413 }
2414 Type::User(UserType::Enum(enum_def)) => {
2415 serialize_enum_from_dynamic(serializer, dynamic, enum_def, target_shape, value_shape)
2416 }
2417 _ => Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2418 "unsupported target shape for serialize_value_with_shape: {}",
2419 target_shape
2420 )))),
2421 }
2422}
2423
2424fn serialize_option_from_dynamic<S>(
2425 serializer: &mut S,
2426 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2427 inner_shape: &'static Shape,
2428 value_shape: &'static Shape,
2429) -> Result<(), SerializeError<S::Error>>
2430where
2431 S: FormatSerializer,
2432{
2433 if dynamic.kind() == DynValueKind::Null {
2434 serializer.serialize_none().map_err(SerializeError::Backend)
2435 } else {
2436 serializer
2437 .begin_option_some()
2438 .map_err(SerializeError::Backend)?;
2439 serialize_dynamic_with_shape(serializer, dynamic, inner_shape, value_shape)
2440 }
2441}
2442
2443fn serialize_list_from_dynamic<S>(
2444 serializer: &mut S,
2445 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2446 item_shape: &'static Shape,
2447 value_shape: &'static Shape,
2448) -> Result<(), SerializeError<S::Error>>
2449where
2450 S: FormatSerializer,
2451{
2452 let len = dynamic.array_len().ok_or_else(|| {
2453 SerializeError::Unsupported(Cow::Borrowed(
2454 "expected array value for list/vec target shape",
2455 ))
2456 })?;
2457
2458 serializer
2459 .begin_seq_with_len(len)
2460 .map_err(SerializeError::Backend)?;
2461
2462 if let Some(iter) = dynamic.array_iter() {
2463 for elem in iter {
2464 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2465 SerializeError::Internal(Cow::Borrowed("array element is not a dynamic value"))
2466 })?;
2467 serialize_dynamic_with_shape(serializer, elem_dyn, item_shape, value_shape)?;
2468 }
2469 }
2470
2471 serializer.end_seq().map_err(SerializeError::Backend)
2472}
2473
2474fn serialize_array_from_dynamic<S>(
2475 serializer: &mut S,
2476 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2477 item_shape: &'static Shape,
2478 value_shape: &'static Shape,
2479) -> Result<(), SerializeError<S::Error>>
2480where
2481 S: FormatSerializer,
2482{
2483 serializer.begin_seq().map_err(SerializeError::Backend)?;
2485
2486 if let Some(iter) = dynamic.array_iter() {
2487 for elem in iter {
2488 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2489 SerializeError::Internal(Cow::Borrowed("array element is not a dynamic value"))
2490 })?;
2491 serialize_dynamic_with_shape(serializer, elem_dyn, item_shape, value_shape)?;
2492 }
2493 }
2494
2495 serializer.end_seq().map_err(SerializeError::Backend)
2496}
2497
2498fn serialize_map_from_dynamic<S>(
2499 serializer: &mut S,
2500 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2501 key_shape: &'static Shape,
2502 value_shape_inner: &'static Shape,
2503 value_shape: &'static Shape,
2504) -> Result<(), SerializeError<S::Error>>
2505where
2506 S: FormatSerializer,
2507{
2508 let len = dynamic.object_len().ok_or_else(|| {
2509 SerializeError::Unsupported(Cow::Borrowed("expected object value for map target shape"))
2510 })?;
2511
2512 match serializer.map_encoding() {
2513 MapEncoding::Pairs => {
2514 serializer
2515 .begin_map_with_len(len)
2516 .map_err(SerializeError::Backend)?;
2517
2518 if let Some(iter) = dynamic.object_iter() {
2519 for (key, val) in iter {
2520 serialize_string_as_scalar(serializer, key, key_shape)?;
2522 let val_dyn = val.into_dynamic_value().map_err(|_| {
2524 SerializeError::Internal(Cow::Borrowed(
2525 "object value is not a dynamic value",
2526 ))
2527 })?;
2528 serialize_dynamic_with_shape(
2529 serializer,
2530 val_dyn,
2531 value_shape_inner,
2532 value_shape,
2533 )?;
2534 }
2535 }
2536
2537 serializer.end_map().map_err(SerializeError::Backend)
2538 }
2539 MapEncoding::Struct => {
2540 serializer.begin_struct().map_err(SerializeError::Backend)?;
2541
2542 if let Some(iter) = dynamic.object_iter() {
2543 for (key, val) in iter {
2544 serializer.field_key(key).map_err(SerializeError::Backend)?;
2545 let val_dyn = val.into_dynamic_value().map_err(|_| {
2546 SerializeError::Internal(Cow::Borrowed(
2547 "object value is not a dynamic value",
2548 ))
2549 })?;
2550 serialize_dynamic_with_shape(
2551 serializer,
2552 val_dyn,
2553 value_shape_inner,
2554 value_shape,
2555 )?;
2556 }
2557 }
2558
2559 serializer.end_struct().map_err(SerializeError::Backend)
2560 }
2561 }
2562}
2563
2564fn serialize_string_as_scalar<S>(
2565 serializer: &mut S,
2566 s: &str,
2567 _key_shape: &'static Shape,
2568) -> Result<(), SerializeError<S::Error>>
2569where
2570 S: FormatSerializer,
2571{
2572 serializer
2575 .scalar(ScalarValue::Str(Cow::Borrowed(s)))
2576 .map_err(SerializeError::Backend)
2577}
2578
2579fn serialize_scalar_from_dynamic<S>(
2580 serializer: &mut S,
2581 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2582 scalar_type: facet_core::ScalarType,
2583) -> Result<(), SerializeError<S::Error>>
2584where
2585 S: FormatSerializer,
2586{
2587 use facet_core::ScalarType as ST;
2588
2589 match scalar_type {
2590 ST::Unit => serializer
2591 .scalar(ScalarValue::Null)
2592 .map_err(SerializeError::Backend),
2593 ST::Bool => {
2594 let v = dynamic
2595 .as_bool()
2596 .ok_or_else(|| SerializeError::Unsupported(Cow::Borrowed("expected bool value")))?;
2597 serializer
2598 .scalar(ScalarValue::Bool(v))
2599 .map_err(SerializeError::Backend)
2600 }
2601 ST::Char => {
2602 let s = dynamic.as_str().ok_or_else(|| {
2603 SerializeError::Unsupported(Cow::Borrowed("expected string value for char"))
2604 })?;
2605 let c = s.chars().next().ok_or_else(|| {
2606 SerializeError::Unsupported(Cow::Borrowed("expected non-empty string for char"))
2607 })?;
2608 serializer
2609 .scalar(ScalarValue::Char(c))
2610 .map_err(SerializeError::Backend)
2611 }
2612 ST::Str | ST::String | ST::CowStr => {
2613 let s = dynamic.as_str().ok_or_else(|| {
2614 SerializeError::Unsupported(Cow::Borrowed("expected string value"))
2615 })?;
2616 serializer
2617 .scalar(ScalarValue::Str(Cow::Borrowed(s)))
2618 .map_err(SerializeError::Backend)
2619 }
2620 ST::U8 | ST::U16 | ST::U32 | ST::U64 | ST::USize => {
2621 let n = dynamic.as_u64().ok_or_else(|| {
2622 SerializeError::Unsupported(Cow::Borrowed("expected unsigned integer value"))
2623 })?;
2624 serializer
2625 .scalar(ScalarValue::U64(n))
2626 .map_err(SerializeError::Backend)
2627 }
2628 ST::U128 => {
2629 let n = dynamic.as_u64().ok_or_else(|| {
2630 SerializeError::Unsupported(Cow::Borrowed("expected unsigned integer value"))
2631 })?;
2632 serializer
2633 .scalar(ScalarValue::U128(n as u128))
2634 .map_err(SerializeError::Backend)
2635 }
2636 ST::I8 | ST::I16 | ST::I32 | ST::I64 | ST::ISize => {
2637 let n = dynamic.as_i64().ok_or_else(|| {
2638 SerializeError::Unsupported(Cow::Borrowed("expected signed integer value"))
2639 })?;
2640 serializer
2641 .scalar(ScalarValue::I64(n))
2642 .map_err(SerializeError::Backend)
2643 }
2644 ST::I128 => {
2645 let n = dynamic.as_i64().ok_or_else(|| {
2646 SerializeError::Unsupported(Cow::Borrowed("expected signed integer value"))
2647 })?;
2648 serializer
2649 .scalar(ScalarValue::I128(n as i128))
2650 .map_err(SerializeError::Backend)
2651 }
2652 ST::F32 | ST::F64 => {
2653 let n = dynamic.as_f64().ok_or_else(|| {
2654 SerializeError::Unsupported(Cow::Borrowed("expected float value"))
2655 })?;
2656 serializer
2657 .scalar(ScalarValue::F64(n))
2658 .map_err(SerializeError::Backend)
2659 }
2660 _ => Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2661 "unsupported scalar type: {:?}",
2662 scalar_type
2663 )))),
2664 }
2665}
2666
2667fn serialize_struct_from_dynamic<S>(
2668 serializer: &mut S,
2669 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2670 struct_def: facet_core::StructType,
2671 value_shape: &'static Shape,
2672) -> Result<(), SerializeError<S::Error>>
2673where
2674 S: FormatSerializer,
2675{
2676 let is_tuple = matches!(struct_def.kind, StructKind::Tuple | StructKind::TupleStruct);
2677
2678 if is_tuple {
2679 serializer.begin_seq().map_err(SerializeError::Backend)?;
2681
2682 let iter = dynamic.array_iter().ok_or_else(|| {
2683 SerializeError::Unsupported(Cow::Borrowed("expected array value for tuple"))
2684 })?;
2685
2686 for (field, elem) in struct_def.fields.iter().zip(iter) {
2687 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2688 SerializeError::Internal(Cow::Borrowed("tuple element is not a dynamic value"))
2689 })?;
2690 serialize_dynamic_with_shape(serializer, elem_dyn, field.shape(), value_shape)?;
2691 }
2692
2693 serializer.end_seq().map_err(SerializeError::Backend)
2694 } else {
2695 let field_mode = serializer.struct_field_mode();
2697
2698 serializer.begin_struct().map_err(SerializeError::Backend)?;
2699
2700 for field in struct_def.fields {
2701 if field.is_metadata() {
2703 continue;
2704 }
2705
2706 let field_name = field.name;
2707 let field_value = dynamic.object_get(field_name).ok_or_else(|| {
2708 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2709 "missing field '{}' in object",
2710 field_name
2711 )))
2712 })?;
2713
2714 if field_mode == StructFieldMode::Named {
2715 serializer
2716 .field_key(field_name)
2717 .map_err(SerializeError::Backend)?;
2718 }
2719
2720 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
2721 SerializeError::Internal(Cow::Borrowed("field value is not a dynamic value"))
2722 })?;
2723 serialize_dynamic_with_shape(serializer, field_dyn, field.shape(), value_shape)?;
2724 }
2725
2726 serializer.end_struct().map_err(SerializeError::Backend)
2727 }
2728}
2729
2730fn serialize_enum_from_dynamic<S>(
2731 serializer: &mut S,
2732 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2733 enum_def: facet_core::EnumType,
2734 target_shape: &'static Shape,
2735 value_shape: &'static Shape,
2736) -> Result<(), SerializeError<S::Error>>
2737where
2738 S: FormatSerializer,
2739{
2740 let use_index = serializer.enum_variant_encoding() == EnumVariantEncoding::Index;
2746
2747 match dynamic.kind() {
2748 DynValueKind::String => {
2750 let variant_name = dynamic.as_str().ok_or_else(|| {
2751 SerializeError::Internal(Cow::Borrowed("expected string for unit variant"))
2752 })?;
2753
2754 let (variant_index, variant) = enum_def
2755 .variants
2756 .iter()
2757 .enumerate()
2758 .find(|(_, v)| v.effective_name() == variant_name)
2759 .ok_or_else(|| {
2760 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2761 "unknown variant '{}'",
2762 variant_name
2763 )))
2764 })?;
2765
2766 if use_index {
2767 serializer
2768 .begin_enum_variant(variant_index, variant.effective_name())
2769 .map_err(SerializeError::Backend)?;
2770 Ok(())
2772 } else {
2773 serializer
2774 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
2775 .map_err(SerializeError::Backend)
2776 }
2777 }
2778
2779 DynValueKind::Object => {
2781 let obj_len = dynamic.object_len().unwrap_or(0);
2783 if obj_len != 1 {
2784 return Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2785 "expected single-key object for enum variant, got {} keys",
2786 obj_len
2787 ))));
2788 }
2789
2790 let (variant_name, payload) = dynamic.object_get_entry(0).ok_or_else(|| {
2791 SerializeError::Internal(Cow::Borrowed("expected object entry for enum variant"))
2792 })?;
2793
2794 let (variant_index, variant) = enum_def
2795 .variants
2796 .iter()
2797 .enumerate()
2798 .find(|(_, v)| v.effective_name() == variant_name)
2799 .ok_or_else(|| {
2800 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2801 "unknown variant '{}'",
2802 variant_name
2803 )))
2804 })?;
2805
2806 let payload_dyn = payload.into_dynamic_value().map_err(|_| {
2807 SerializeError::Internal(Cow::Borrowed("variant payload is not a dynamic value"))
2808 })?;
2809
2810 if use_index {
2811 serializer
2812 .begin_enum_variant(variant_index, variant.effective_name())
2813 .map_err(SerializeError::Backend)?;
2814
2815 match variant.data.kind {
2817 StructKind::Unit => {
2818 }
2820 StructKind::TupleStruct | StructKind::Tuple => {
2821 if variant.data.fields.len() == 1 {
2822 serialize_dynamic_with_shape(
2824 serializer,
2825 payload_dyn,
2826 variant.data.fields[0].shape(),
2827 value_shape,
2828 )?;
2829 } else {
2830 let iter = payload_dyn.array_iter().ok_or_else(|| {
2832 SerializeError::Unsupported(Cow::Borrowed(
2833 "expected array for tuple variant payload",
2834 ))
2835 })?;
2836
2837 for (field, elem) in variant.data.fields.iter().zip(iter) {
2838 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2839 SerializeError::Internal(Cow::Borrowed(
2840 "tuple element is not a dynamic value",
2841 ))
2842 })?;
2843 serialize_dynamic_with_shape(
2844 serializer,
2845 elem_dyn,
2846 field.shape(),
2847 value_shape,
2848 )?;
2849 }
2850 }
2851 }
2852 StructKind::Struct => {
2853 for field in variant.data.fields {
2855 let field_value =
2856 payload_dyn.object_get(field.name).ok_or_else(|| {
2857 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2858 "missing field '{}' in struct variant",
2859 field.name
2860 )))
2861 })?;
2862 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
2863 SerializeError::Internal(Cow::Borrowed(
2864 "field value is not a dynamic value",
2865 ))
2866 })?;
2867 serialize_dynamic_with_shape(
2868 serializer,
2869 field_dyn,
2870 field.shape(),
2871 value_shape,
2872 )?;
2873 }
2874 }
2875 }
2876
2877 Ok(())
2878 } else {
2879 serializer.begin_struct().map_err(SerializeError::Backend)?;
2881 serializer
2882 .field_key(variant.effective_name())
2883 .map_err(SerializeError::Backend)?;
2884
2885 match variant.data.kind {
2886 StructKind::Unit => {
2887 serializer
2888 .scalar(ScalarValue::Null)
2889 .map_err(SerializeError::Backend)?;
2890 }
2891 StructKind::TupleStruct | StructKind::Tuple => {
2892 if variant.data.fields.len() == 1 {
2893 serialize_dynamic_with_shape(
2894 serializer,
2895 payload_dyn,
2896 variant.data.fields[0].shape(),
2897 value_shape,
2898 )?;
2899 } else {
2900 serializer.begin_seq().map_err(SerializeError::Backend)?;
2901 let iter = payload_dyn.array_iter().ok_or_else(|| {
2902 SerializeError::Unsupported(Cow::Borrowed(
2903 "expected array for tuple variant",
2904 ))
2905 })?;
2906 for (field, elem) in variant.data.fields.iter().zip(iter) {
2907 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2908 SerializeError::Internal(Cow::Borrowed(
2909 "element is not a dynamic value",
2910 ))
2911 })?;
2912 serialize_dynamic_with_shape(
2913 serializer,
2914 elem_dyn,
2915 field.shape(),
2916 value_shape,
2917 )?;
2918 }
2919 serializer.end_seq().map_err(SerializeError::Backend)?;
2920 }
2921 }
2922 StructKind::Struct => {
2923 serializer.begin_struct().map_err(SerializeError::Backend)?;
2924 for field in variant.data.fields {
2925 let field_value =
2926 payload_dyn.object_get(field.name).ok_or_else(|| {
2927 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2928 "missing field '{}'",
2929 field.name
2930 )))
2931 })?;
2932 serializer
2933 .field_key(field.name)
2934 .map_err(SerializeError::Backend)?;
2935 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
2936 SerializeError::Internal(Cow::Borrowed(
2937 "field is not a dynamic value",
2938 ))
2939 })?;
2940 serialize_dynamic_with_shape(
2941 serializer,
2942 field_dyn,
2943 field.shape(),
2944 value_shape,
2945 )?;
2946 }
2947 serializer.end_struct().map_err(SerializeError::Backend)?;
2948 }
2949 }
2950
2951 serializer.end_struct().map_err(SerializeError::Backend)
2952 }
2953 }
2954
2955 DynValueKind::Null => {
2957 if let Some((variant_index, variant)) = enum_def
2960 .variants
2961 .iter()
2962 .enumerate()
2963 .find(|(_, v)| v.name.eq_ignore_ascii_case("null") || v.name == "None")
2964 {
2965 if use_index {
2966 serializer
2967 .begin_enum_variant(variant_index, variant.effective_name())
2968 .map_err(SerializeError::Backend)?;
2969 Ok(())
2970 } else {
2971 serializer
2972 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
2973 .map_err(SerializeError::Backend)
2974 }
2975 } else {
2976 Err(SerializeError::Unsupported(Cow::Borrowed(
2977 "null value for enum without null/None variant",
2978 )))
2979 }
2980 }
2981
2982 _ => {
2983 let _ = target_shape; Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2987 "unsupported dynamic value kind {:?} for enum serialization",
2988 dynamic.kind()
2989 ))))
2990 }
2991 }
2992}