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_discriminant<'mem, 'facet>(
1129 &mut self,
1130 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1131 ) -> Result<(), SerializeError<S::Error>> {
1132 match enum_.ty().enum_repr {
1133 facet_core::EnumRepr::Rust => Err(SerializeError::Internal(Cow::Borrowed(
1134 "enum does not have an explicit representation",
1135 ))),
1136 facet_core::EnumRepr::RustNPO
1137 | facet_core::EnumRepr::U8
1138 | facet_core::EnumRepr::U16
1139 | facet_core::EnumRepr::U32
1140 | facet_core::EnumRepr::U64
1141 | facet_core::EnumRepr::USize => self
1142 .serializer
1143 .scalar(ScalarValue::U64(enum_.discriminant() as u64))
1144 .map_err(SerializeError::Backend),
1145 facet_core::EnumRepr::I8
1146 | facet_core::EnumRepr::I16
1147 | facet_core::EnumRepr::I32
1148 | facet_core::EnumRepr::I64
1149 | facet_core::EnumRepr::ISize => self
1150 .serializer
1151 .scalar(ScalarValue::I64(enum_.discriminant()))
1152 .map_err(SerializeError::Backend),
1153 }
1154 }
1155
1156 fn serialize_enum<'mem, 'facet>(
1157 &mut self,
1158 shape: &'static Shape,
1159 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1160 ) -> Result<(), SerializeError<S::Error>> {
1161 let variant = enum_.active_variant().map_err(|_| {
1162 SerializeError::Unsupported(Cow::Borrowed("opaque enum layout is unsupported"))
1163 })?;
1164
1165 self.serializer
1166 .variant_metadata(variant)
1167 .map_err(SerializeError::Backend)?;
1168
1169 if shape.is_cow() {
1171 let inner = enum_
1172 .field(0)
1173 .map_err(|_| {
1174 SerializeError::Internal(Cow::Borrowed("cow variant field lookup failed"))
1175 })?
1176 .ok_or(SerializeError::Internal(Cow::Borrowed(
1177 "cow variant has no field",
1178 )))?;
1179 return self.serialize_impl(inner);
1180 }
1181
1182 if self.serializer.enum_variant_encoding() == EnumVariantEncoding::Index {
1183 let variant_index = enum_.variant_index().map_err(|_| {
1184 SerializeError::Unsupported(Cow::Borrowed("opaque enum layout is unsupported"))
1185 })?;
1186 self.serializer
1187 .begin_enum_variant(variant_index, variant.name)
1188 .map_err(SerializeError::Backend)?;
1189
1190 self.push(PathSegment::Variant(Cow::Borrowed(variant.name)));
1191 let result = match variant.data.kind {
1192 StructKind::Unit => Ok(()),
1193 StructKind::TupleStruct | StructKind::Tuple | StructKind::Struct => {
1194 for (idx, (field_item, field_value)) in
1195 enum_.fields_for_binary_serialize().enumerate()
1196 {
1197 self.push(PathSegment::Index(idx));
1198 self.serialize_field_value(&field_item, field_value)?;
1199 self.pop();
1200 }
1201 Ok(())
1202 }
1203 };
1204 self.pop();
1205 return result;
1206 }
1207
1208 let numeric = shape.is_numeric();
1209 let untagged = shape.is_untagged();
1210 let tag = shape.get_tag_attr();
1211 let content = shape.get_content_attr();
1212
1213 if numeric && tag.is_none() {
1214 return serialize_numeric_enum(self.serializer, variant);
1215 }
1216 if untagged {
1217 self.push(PathSegment::Variant(Cow::Borrowed(
1218 variant.effective_name(),
1219 )));
1220 let result = self.serialize_untagged_enum(enum_, variant);
1221 self.pop();
1222 return result;
1223 }
1224
1225 if variant.is_other() {
1229 let has_tag_field = variant.data.fields.iter().any(|f| f.is_variant_tag());
1230 if !has_tag_field {
1231 self.push(PathSegment::Variant(Cow::Borrowed(
1232 variant.effective_name(),
1233 )));
1234 let result = self.serialize_untagged_enum(enum_, variant);
1235 self.pop();
1236 return result;
1237 }
1238 }
1239
1240 match (tag, content) {
1241 (Some(tag_key), None) => {
1242 self.serializer
1244 .begin_struct()
1245 .map_err(SerializeError::Backend)?;
1246 self.serializer
1247 .field_key(tag_key)
1248 .map_err(SerializeError::Backend)?;
1249
1250 if numeric {
1251 self.serialize_discriminant(enum_)?;
1252 } else {
1253 self.serializer
1254 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1255 .map_err(SerializeError::Backend)?;
1256 }
1257
1258 self.push(PathSegment::Variant(Cow::Borrowed(
1259 variant.effective_name(),
1260 )));
1261 let field_mode = self.serializer.struct_field_mode();
1262 match variant.data.kind {
1263 StructKind::Unit => {}
1264 StructKind::Struct => {
1265 let mut fields: alloc::vec::Vec<_> =
1266 if field_mode == StructFieldMode::Unnamed {
1267 enum_.fields_for_binary_serialize().collect()
1268 } else {
1269 enum_.fields_for_serialize().collect()
1270 };
1271 sort_fields_if_needed(self.serializer, &mut fields);
1272 for (field_item, field_value) in fields {
1273 self.serializer
1274 .field_metadata(&field_item)
1275 .map_err(SerializeError::Backend)?;
1276 if field_mode == StructFieldMode::Named {
1277 self.serializer
1278 .field_key(field_item.effective_name())
1279 .map_err(SerializeError::Backend)?;
1280 }
1281 self.push(PathSegment::Field(Cow::Owned(
1282 field_item.effective_name().to_string(),
1283 )));
1284 self.serialize_field_value(&field_item, field_value)?;
1285 self.pop();
1286 }
1287 }
1288 StructKind::TupleStruct | StructKind::Tuple => {
1289 if variant.data.fields.len() != 1 {
1292 self.pop();
1293 return Err(SerializeError::Unsupported(Cow::Borrowed(
1294 "internally tagged tuple variants are not supported",
1295 )));
1296 }
1297
1298 let inner_shape = variant.data.fields[0].shape();
1299 let inner_tag = match inner_shape.get_tag_attr() {
1300 Some(tag) if inner_shape.get_content_attr().is_none() => tag,
1301 _ => {
1302 self.pop();
1303 return Err(SerializeError::Unsupported(Cow::Borrowed(
1304 "internally tagged tuple variants are not supported",
1305 )));
1306 }
1307 };
1308
1309 let inner_value = enum_
1310 .field(0)
1311 .map_err(|e| SerializeError::Unsupported(Cow::Owned(e.to_string())))?
1312 .expect("single-field tuple variant should have field 0");
1313
1314 let inner_enum = inner_value.into_enum().map_err(|_| {
1315 SerializeError::Unsupported(Cow::Borrowed(
1316 "internally tagged tuple variant field is not an enum",
1317 ))
1318 })?;
1319
1320 let inner_variant = inner_enum
1321 .active_variant()
1322 .map_err(|e| SerializeError::Unsupported(Cow::Owned(e.to_string())))?;
1323
1324 self.serializer
1326 .field_key(inner_tag)
1327 .map_err(SerializeError::Backend)?;
1328 self.serializer
1329 .scalar(ScalarValue::Str(Cow::Borrowed(
1330 inner_variant.effective_name(),
1331 )))
1332 .map_err(SerializeError::Backend)?;
1333
1334 self.push(PathSegment::Variant(Cow::Borrowed(
1336 inner_variant.effective_name(),
1337 )));
1338
1339 match inner_variant.data.kind {
1340 StructKind::Unit => {}
1341 StructKind::Struct => {
1342 let mut inner_fields: alloc::vec::Vec<_> =
1343 if field_mode == StructFieldMode::Unnamed {
1344 inner_enum.fields_for_binary_serialize().collect()
1345 } else {
1346 inner_enum.fields_for_serialize().collect()
1347 };
1348 sort_fields_if_needed(self.serializer, &mut inner_fields);
1349
1350 for (field_item, field_value) in inner_fields {
1351 self.serializer
1352 .field_metadata(&field_item)
1353 .map_err(SerializeError::Backend)?;
1354 if field_mode == StructFieldMode::Named {
1355 self.serializer
1356 .field_key(field_item.effective_name())
1357 .map_err(SerializeError::Backend)?;
1358 }
1359 self.push(PathSegment::Field(Cow::Owned(
1360 field_item.effective_name().to_string(),
1361 )));
1362 self.serialize_field_value(&field_item, field_value)?;
1363 self.pop();
1364 }
1365 }
1366 StructKind::TupleStruct | StructKind::Tuple => {
1367 self.pop();
1368 self.pop();
1369 return Err(SerializeError::Unsupported(Cow::Borrowed(
1370 "nested internally tagged tuple variants are not supported",
1371 )));
1372 }
1373 }
1374
1375 self.pop();
1376 }
1377 }
1378 self.pop();
1379
1380 self.serializer
1381 .end_struct()
1382 .map_err(SerializeError::Backend)?;
1383 return Ok(());
1384 }
1385 (Some(tag_key), Some(content_key)) => {
1386 return self.serialize_adjacently_tagged_enum(
1388 enum_,
1389 variant,
1390 tag_key,
1391 content_key,
1392 numeric,
1393 );
1394 }
1395 (None, Some(_)) => {
1396 return Err(SerializeError::Unsupported(Cow::Borrowed(
1397 "adjacent content key set without tag key",
1398 )));
1399 }
1400 (None, None) => {}
1401 }
1402
1403 self.serialize_externally_tagged_enum(enum_, variant)
1405 }
1406
1407 fn serialize_adjacently_tagged_enum<'mem, 'facet>(
1408 &mut self,
1409 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1410 variant: &'static facet_core::Variant,
1411 tag_key: &'static str,
1412 content_key: &'static str,
1413 numeric: bool,
1414 ) -> Result<(), SerializeError<S::Error>> {
1415 let field_mode = self.serializer.struct_field_mode();
1416 self.serializer
1417 .begin_struct()
1418 .map_err(SerializeError::Backend)?;
1419 self.serializer
1420 .field_key(tag_key)
1421 .map_err(SerializeError::Backend)?;
1422
1423 if numeric {
1424 self.serialize_discriminant(enum_)?;
1425 } else {
1426 self.serializer
1427 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1428 .map_err(SerializeError::Backend)?;
1429 }
1430
1431 self.push(PathSegment::Variant(Cow::Borrowed(
1432 variant.effective_name(),
1433 )));
1434
1435 match variant.data.kind {
1436 StructKind::Unit => {}
1437 StructKind::Struct => {
1438 self.serializer
1439 .field_key(content_key)
1440 .map_err(SerializeError::Backend)?;
1441 self.serializer
1442 .begin_struct()
1443 .map_err(SerializeError::Backend)?;
1444 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1445 enum_.fields_for_binary_serialize().collect()
1446 } else {
1447 enum_.fields_for_serialize().collect()
1448 };
1449 sort_fields_if_needed(self.serializer, &mut fields);
1450 for (field_item, field_value) in fields {
1451 self.serializer
1452 .field_metadata(&field_item)
1453 .map_err(SerializeError::Backend)?;
1454 if field_mode == StructFieldMode::Named {
1455 self.serializer
1456 .field_key(field_item.effective_name())
1457 .map_err(SerializeError::Backend)?;
1458 }
1459 self.push(PathSegment::Field(Cow::Owned(
1460 field_item.effective_name().to_string(),
1461 )));
1462 self.serialize_field_value(&field_item, field_value)?;
1463 self.pop();
1464 }
1465 self.serializer
1466 .end_struct()
1467 .map_err(SerializeError::Backend)?;
1468 }
1469 StructKind::TupleStruct | StructKind::Tuple => {
1470 self.serializer
1471 .field_key(content_key)
1472 .map_err(SerializeError::Backend)?;
1473
1474 let field_count = variant.data.fields.len();
1475 if field_count == 1 {
1476 let inner = enum_
1477 .field(0)
1478 .map_err(|_| {
1479 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1480 })?
1481 .ok_or(SerializeError::Internal(Cow::Borrowed(
1482 "variant reported 1 field but field(0) returned None",
1483 )))?;
1484 let field_def = variant.data.fields.first().copied();
1485 self.with_field_context(field_def, |this| this.serialize_impl(inner))?;
1486 } else {
1487 self.serializer
1488 .begin_seq()
1489 .map_err(SerializeError::Backend)?;
1490 for idx in 0..field_count {
1491 let inner = enum_
1492 .field(idx)
1493 .map_err(|_| {
1494 SerializeError::Internal(Cow::Borrowed(
1495 "variant field lookup failed",
1496 ))
1497 })?
1498 .ok_or(SerializeError::Internal(Cow::Borrowed(
1499 "variant field missing while iterating tuple fields",
1500 )))?;
1501 self.push(PathSegment::Index(idx));
1502 let field_def = variant.data.fields.get(idx).copied();
1503 self.with_field_context(field_def, |this| this.serialize_impl(inner))?;
1504 self.pop();
1505 }
1506 self.serializer.end_seq().map_err(SerializeError::Backend)?;
1507 }
1508 }
1509 }
1510
1511 self.pop();
1512 self.serializer
1513 .end_struct()
1514 .map_err(SerializeError::Backend)?;
1515 Ok(())
1516 }
1517
1518 fn serialize_externally_tagged_enum<'mem, 'facet>(
1519 &mut self,
1520 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1521 variant: &'static facet_core::Variant,
1522 ) -> Result<(), SerializeError<S::Error>> {
1523 let field_mode = self.serializer.struct_field_mode();
1524
1525 let tag_name: Cow<'_, str> = if variant.is_other() {
1528 let mut tag_value: Option<Cow<'_, str>> = None;
1529 let fields_iter: alloc::boxed::Box<
1530 dyn Iterator<Item = (facet_reflect::FieldItem, facet_reflect::Peek<'_, '_>)>,
1531 > = if field_mode == StructFieldMode::Unnamed {
1532 alloc::boxed::Box::new(enum_.fields_for_binary_serialize())
1533 } else {
1534 alloc::boxed::Box::new(enum_.fields_for_serialize())
1535 };
1536 for (field_item, field_value) in fields_iter {
1537 if let Some(field) = field_item.field
1538 && field.is_variant_tag()
1539 {
1540 if let Ok(opt) = field_value.into_option()
1541 && let Some(inner) = opt.value()
1542 && let Some(s) = inner.as_str()
1543 {
1544 tag_value = Some(Cow::Borrowed(s));
1545 }
1546 break;
1547 }
1548 }
1549 tag_value.unwrap_or_else(|| Cow::Borrowed(variant.effective_name()))
1550 } else {
1551 Cow::Borrowed(variant.effective_name())
1552 };
1553
1554 let use_tag_syntax = self
1556 .serializer
1557 .write_variant_tag(&tag_name)
1558 .map_err(SerializeError::Backend)?;
1559
1560 self.push(PathSegment::Variant(Cow::Owned(tag_name.to_string())));
1561
1562 let result = if use_tag_syntax {
1563 self.serialize_variant_after_tag(enum_, variant)
1564 } else {
1565 self.serialize_standard_externally_tagged(enum_, variant)
1566 };
1567
1568 self.pop();
1569 result
1570 }
1571
1572 fn serialize_variant_after_tag<'mem, 'facet>(
1573 &mut self,
1574 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1575 variant: &'static facet_core::Variant,
1576 ) -> Result<(), SerializeError<S::Error>> {
1577 let field_mode = self.serializer.struct_field_mode();
1578
1579 match variant.data.kind {
1580 StructKind::Unit => {
1581 self.serializer
1582 .finish_variant_tag_unit_payload()
1583 .map_err(SerializeError::Backend)?;
1584 Ok(())
1585 }
1586 StructKind::TupleStruct | StructKind::Tuple => {
1587 let field_count = variant.data.fields.len();
1588 if field_count == 1 {
1589 let inner = enum_
1590 .field(0)
1591 .map_err(|_| {
1592 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1593 })?
1594 .ok_or(SerializeError::Internal(Cow::Borrowed(
1595 "variant reported 1 field but field(0) returned None",
1596 )))?;
1597 if let Some(field_def) = variant.data.fields.first().copied()
1598 && let Some(proxy_def) =
1599 field_def.effective_proxy(self.serializer.format_namespace())
1600 {
1601 self.with_field_context(Some(field_def), |this| {
1602 this.serialize_via_proxy(inner, proxy_def)
1603 })?;
1604 } else {
1605 self.with_field_context(variant.data.fields.first().copied(), |this| {
1606 this.serialize_impl(inner)
1607 })?;
1608 }
1609 } else {
1610 self.serializer
1611 .begin_seq_after_tag()
1612 .map_err(SerializeError::Backend)?;
1613 for idx in 0..field_count {
1614 let inner = enum_
1615 .field(idx)
1616 .map_err(|_| {
1617 SerializeError::Internal(Cow::Borrowed(
1618 "variant field lookup failed",
1619 ))
1620 })?
1621 .ok_or(SerializeError::Internal(Cow::Borrowed(
1622 "variant field missing while iterating tuple fields",
1623 )))?;
1624 self.push(PathSegment::Index(idx));
1625 if let Some(field_def) = variant.data.fields.get(idx).copied()
1626 && let Some(proxy_def) =
1627 field_def.effective_proxy(self.serializer.format_namespace())
1628 {
1629 self.with_field_context(Some(field_def), |this| {
1630 this.serialize_via_proxy(inner, proxy_def)
1631 })?;
1632 } else {
1633 self.with_field_context(
1634 variant.data.fields.get(idx).copied(),
1635 |this| this.serialize_impl(inner),
1636 )?;
1637 }
1638 self.pop();
1639 }
1640 self.serializer.end_seq().map_err(SerializeError::Backend)?;
1641 }
1642 Ok(())
1643 }
1644 StructKind::Struct => {
1645 let is_other = variant.is_other();
1646 let fields_iter: alloc::boxed::Box<
1647 dyn Iterator<Item = (facet_reflect::FieldItem, facet_reflect::Peek<'_, '_>)>,
1648 > = if field_mode == StructFieldMode::Unnamed {
1649 alloc::boxed::Box::new(enum_.fields_for_binary_serialize())
1650 } else {
1651 alloc::boxed::Box::new(enum_.fields_for_serialize())
1652 };
1653 let mut fields: alloc::vec::Vec<_> = fields_iter
1654 .filter(|(field_item, _)| {
1655 if is_other {
1656 field_item
1657 .field
1658 .map(|f| f.metadata_kind().is_none() && !f.is_variant_tag())
1659 .unwrap_or(true)
1660 } else {
1661 true
1662 }
1663 })
1664 .collect();
1665
1666 if fields.is_empty() {
1667 self.serializer
1668 .finish_variant_tag_unit_payload()
1669 .map_err(SerializeError::Backend)?;
1670 return Ok(());
1671 }
1672
1673 self.serializer
1674 .begin_struct_after_tag()
1675 .map_err(SerializeError::Backend)?;
1676 sort_fields_if_needed(self.serializer, &mut fields);
1677 for (field_item, field_value) in fields {
1678 self.serializer
1679 .field_metadata(&field_item)
1680 .map_err(SerializeError::Backend)?;
1681 if field_mode == StructFieldMode::Named {
1682 self.serializer
1683 .field_key(field_item.effective_name())
1684 .map_err(SerializeError::Backend)?;
1685 }
1686 self.push(PathSegment::Field(Cow::Owned(
1687 field_item.effective_name().to_string(),
1688 )));
1689 self.serialize_field_value(&field_item, field_value)?;
1690 self.pop();
1691 }
1692 self.serializer
1693 .end_struct()
1694 .map_err(SerializeError::Backend)?;
1695 Ok(())
1696 }
1697 }
1698 }
1699
1700 fn serialize_standard_externally_tagged<'mem, 'facet>(
1701 &mut self,
1702 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1703 variant: &'static facet_core::Variant,
1704 ) -> Result<(), SerializeError<S::Error>> {
1705 let field_mode = self.serializer.struct_field_mode();
1706
1707 match variant.data.kind {
1708 StructKind::Unit => {
1709 self.serializer
1710 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1711 .map_err(SerializeError::Backend)?;
1712 Ok(())
1713 }
1714 StructKind::TupleStruct | StructKind::Tuple => {
1715 self.serializer
1716 .begin_struct()
1717 .map_err(SerializeError::Backend)?;
1718 self.serializer
1719 .field_key(variant.effective_name())
1720 .map_err(SerializeError::Backend)?;
1721
1722 let field_count = variant.data.fields.len();
1723 if field_count == 1 {
1724 let inner = enum_
1725 .field(0)
1726 .map_err(|_| {
1727 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1728 })?
1729 .ok_or(SerializeError::Internal(Cow::Borrowed(
1730 "variant reported 1 field but field(0) returned None",
1731 )))?;
1732 if let Some(field_def) = variant.data.fields.first().copied()
1733 && let Some(proxy_def) =
1734 field_def.effective_proxy(self.serializer.format_namespace())
1735 {
1736 self.with_field_context(Some(field_def), |this| {
1737 this.serialize_via_proxy(inner, proxy_def)
1738 })?;
1739 } else {
1740 self.with_field_context(variant.data.fields.first().copied(), |this| {
1741 this.serialize_impl(inner)
1742 })?;
1743 }
1744 } else {
1745 self.serializer
1746 .begin_seq()
1747 .map_err(SerializeError::Backend)?;
1748 for idx in 0..field_count {
1749 let inner = enum_
1750 .field(idx)
1751 .map_err(|_| {
1752 SerializeError::Internal(Cow::Borrowed(
1753 "variant field lookup failed",
1754 ))
1755 })?
1756 .ok_or(SerializeError::Internal(Cow::Borrowed(
1757 "variant field missing while iterating tuple fields",
1758 )))?;
1759 self.push(PathSegment::Index(idx));
1760 if let Some(field_def) = variant.data.fields.get(idx).copied()
1761 && let Some(proxy_def) =
1762 field_def.effective_proxy(self.serializer.format_namespace())
1763 {
1764 self.with_field_context(Some(field_def), |this| {
1765 this.serialize_via_proxy(inner, proxy_def)
1766 })?;
1767 } else {
1768 self.with_field_context(
1769 variant.data.fields.get(idx).copied(),
1770 |this| this.serialize_impl(inner),
1771 )?;
1772 }
1773 self.pop();
1774 }
1775 self.serializer.end_seq().map_err(SerializeError::Backend)?;
1776 }
1777
1778 self.serializer
1779 .end_struct()
1780 .map_err(SerializeError::Backend)?;
1781 Ok(())
1782 }
1783 StructKind::Struct => {
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 self.serializer
1792 .begin_struct()
1793 .map_err(SerializeError::Backend)?;
1794 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1795 enum_.fields_for_binary_serialize().collect()
1796 } else {
1797 enum_.fields_for_serialize().collect()
1798 };
1799 sort_fields_if_needed(self.serializer, &mut fields);
1800 for (field_item, field_value) in fields {
1801 self.serializer
1802 .field_metadata(&field_item)
1803 .map_err(SerializeError::Backend)?;
1804 if field_mode == StructFieldMode::Named {
1805 self.serializer
1806 .field_key(field_item.effective_name())
1807 .map_err(SerializeError::Backend)?;
1808 }
1809 self.push(PathSegment::Field(Cow::Owned(
1810 field_item.effective_name().to_string(),
1811 )));
1812 self.serialize_field_value(&field_item, field_value)?;
1813 self.pop();
1814 }
1815 self.serializer
1816 .end_struct()
1817 .map_err(SerializeError::Backend)?;
1818
1819 self.serializer
1820 .end_struct()
1821 .map_err(SerializeError::Backend)?;
1822 Ok(())
1823 }
1824 }
1825 }
1826
1827 fn serialize_untagged_enum<'mem, 'facet>(
1828 &mut self,
1829 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1830 variant: &'static facet_core::Variant,
1831 ) -> Result<(), SerializeError<S::Error>> {
1832 let field_mode = self.serializer.struct_field_mode();
1833
1834 match variant.data.kind {
1835 StructKind::Unit => self
1836 .serializer
1837 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1838 .map_err(SerializeError::Backend),
1839 StructKind::TupleStruct | StructKind::Tuple => {
1840 let field_count = variant.data.fields.len();
1841 if field_count == 1 {
1842 let inner = enum_
1843 .field(0)
1844 .map_err(|_| {
1845 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1846 })?
1847 .ok_or(SerializeError::Internal(Cow::Borrowed(
1848 "variant reported 1 field but field(0) returned None",
1849 )))?;
1850 let field_def = variant.data.fields.first().copied();
1851 self.with_field_context(field_def, |this| this.serialize_impl(inner))
1852 } else {
1853 self.serializer
1854 .begin_seq()
1855 .map_err(SerializeError::Backend)?;
1856 for idx in 0..field_count {
1857 let inner = enum_
1858 .field(idx)
1859 .map_err(|_| {
1860 SerializeError::Internal(Cow::Borrowed(
1861 "variant field lookup failed",
1862 ))
1863 })?
1864 .ok_or(SerializeError::Internal(Cow::Borrowed(
1865 "variant field missing while iterating tuple fields",
1866 )))?;
1867 self.push(PathSegment::Index(idx));
1868 let field_def = variant.data.fields.get(idx).copied();
1869 self.with_field_context(field_def, |this| this.serialize_impl(inner))?;
1870 self.pop();
1871 }
1872 self.serializer.end_seq().map_err(SerializeError::Backend)?;
1873 Ok(())
1874 }
1875 }
1876 StructKind::Struct => {
1877 self.serializer
1878 .begin_struct()
1879 .map_err(SerializeError::Backend)?;
1880 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1881 enum_.fields_for_binary_serialize().collect()
1882 } else {
1883 enum_.fields_for_serialize().collect()
1884 };
1885 sort_fields_if_needed(self.serializer, &mut fields);
1886 for (field_item, field_value) in fields {
1887 self.serializer
1888 .field_metadata(&field_item)
1889 .map_err(SerializeError::Backend)?;
1890 if field_mode == StructFieldMode::Named {
1891 self.serializer
1892 .field_key(field_item.effective_name())
1893 .map_err(SerializeError::Backend)?;
1894 }
1895 self.push(PathSegment::Field(Cow::Owned(
1896 field_item.effective_name().to_string(),
1897 )));
1898 self.serialize_field_value(&field_item, field_value)?;
1899 self.pop();
1900 }
1901 self.serializer
1902 .end_struct()
1903 .map_err(SerializeError::Backend)?;
1904 Ok(())
1905 }
1906 }
1907 }
1908
1909 fn serialize_dynamic_value<'mem, 'facet>(
1910 &mut self,
1911 dynamic: facet_reflect::PeekDynamicValue<'mem, 'facet>,
1912 ) -> Result<(), SerializeError<S::Error>> {
1913 let tagged = self.serializer.dynamic_value_encoding() == DynamicValueEncoding::Tagged;
1914
1915 match dynamic.kind() {
1916 DynValueKind::Null => {
1917 if tagged {
1918 self.serializer
1919 .dynamic_value_tag(DynamicValueTag::Null)
1920 .map_err(SerializeError::Backend)?;
1921 }
1922 self.serializer
1923 .scalar(ScalarValue::Null)
1924 .map_err(SerializeError::Backend)
1925 }
1926 DynValueKind::Bool => {
1927 let value = dynamic.as_bool().ok_or_else(|| {
1928 SerializeError::Internal(Cow::Borrowed("dynamic bool missing value"))
1929 })?;
1930 if tagged {
1931 self.serializer
1932 .dynamic_value_tag(DynamicValueTag::Bool)
1933 .map_err(SerializeError::Backend)?;
1934 }
1935 self.serializer
1936 .scalar(ScalarValue::Bool(value))
1937 .map_err(SerializeError::Backend)
1938 }
1939 DynValueKind::Number => {
1940 if let Some(n) = dynamic.as_i64() {
1941 if tagged {
1942 self.serializer
1943 .dynamic_value_tag(DynamicValueTag::I64)
1944 .map_err(SerializeError::Backend)?;
1945 }
1946 self.serializer
1947 .scalar(ScalarValue::I64(n))
1948 .map_err(SerializeError::Backend)
1949 } else if let Some(n) = dynamic.as_u64() {
1950 if tagged {
1951 self.serializer
1952 .dynamic_value_tag(DynamicValueTag::U64)
1953 .map_err(SerializeError::Backend)?;
1954 }
1955 self.serializer
1956 .scalar(ScalarValue::U64(n))
1957 .map_err(SerializeError::Backend)
1958 } else if let Some(n) = dynamic.as_f64() {
1959 if tagged {
1960 self.serializer
1961 .dynamic_value_tag(DynamicValueTag::F64)
1962 .map_err(SerializeError::Backend)?;
1963 }
1964 self.serializer
1965 .scalar(ScalarValue::F64(n))
1966 .map_err(SerializeError::Backend)
1967 } else {
1968 Err(SerializeError::Unsupported(Cow::Borrowed(
1969 "dynamic number not representable",
1970 )))
1971 }
1972 }
1973 DynValueKind::String => {
1974 let value = dynamic.as_str().ok_or_else(|| {
1975 SerializeError::Internal(Cow::Borrowed("dynamic string missing value"))
1976 })?;
1977 if tagged {
1978 self.serializer
1979 .dynamic_value_tag(DynamicValueTag::String)
1980 .map_err(SerializeError::Backend)?;
1981 }
1982 self.serializer
1983 .scalar(ScalarValue::Str(Cow::Borrowed(value)))
1984 .map_err(SerializeError::Backend)
1985 }
1986 DynValueKind::Bytes => {
1987 let value = dynamic.as_bytes().ok_or_else(|| {
1988 SerializeError::Internal(Cow::Borrowed("dynamic bytes missing value"))
1989 })?;
1990 if tagged {
1991 self.serializer
1992 .dynamic_value_tag(DynamicValueTag::Bytes)
1993 .map_err(SerializeError::Backend)?;
1994 }
1995 self.serializer
1996 .scalar(ScalarValue::Bytes(Cow::Borrowed(value)))
1997 .map_err(SerializeError::Backend)
1998 }
1999 DynValueKind::Array => {
2000 let len = dynamic.array_len().ok_or_else(|| {
2001 SerializeError::Internal(Cow::Borrowed("dynamic array missing length"))
2002 })?;
2003 if tagged {
2004 self.serializer
2005 .dynamic_value_tag(DynamicValueTag::Array)
2006 .map_err(SerializeError::Backend)?;
2007 }
2008 self.serializer
2009 .begin_seq_with_len(len)
2010 .map_err(SerializeError::Backend)?;
2011 if let Some(iter) = dynamic.array_iter() {
2012 for (idx, item) in iter.enumerate() {
2013 self.push(PathSegment::Index(idx));
2014 self.serialize_impl(item)?;
2015 self.pop();
2016 }
2017 }
2018 self.serializer.end_seq().map_err(SerializeError::Backend)
2019 }
2020 DynValueKind::Object => {
2021 let len = dynamic.object_len().ok_or_else(|| {
2022 SerializeError::Internal(Cow::Borrowed("dynamic object missing length"))
2023 })?;
2024 if tagged {
2025 self.serializer
2026 .dynamic_value_tag(DynamicValueTag::Object)
2027 .map_err(SerializeError::Backend)?;
2028 }
2029 match self.serializer.map_encoding() {
2030 MapEncoding::Pairs => {
2031 self.serializer
2032 .begin_map_with_len(len)
2033 .map_err(SerializeError::Backend)?;
2034 if let Some(iter) = dynamic.object_iter() {
2035 for (key, value) in iter {
2036 self.serializer
2037 .scalar(ScalarValue::Str(Cow::Borrowed(key)))
2038 .map_err(SerializeError::Backend)?;
2039 self.push(PathSegment::Field(Cow::Owned(key.to_string())));
2040 self.serialize_impl(value)?;
2041 self.pop();
2042 }
2043 }
2044 self.serializer.end_map().map_err(SerializeError::Backend)
2045 }
2046 MapEncoding::Struct => {
2047 self.serializer
2048 .begin_struct()
2049 .map_err(SerializeError::Backend)?;
2050 if let Some(iter) = dynamic.object_iter() {
2051 for (key, value) in iter {
2052 self.serializer
2053 .field_key(key)
2054 .map_err(SerializeError::Backend)?;
2055 self.push(PathSegment::Field(Cow::Owned(key.to_string())));
2056 self.serialize_impl(value)?;
2057 self.pop();
2058 }
2059 }
2060 self.serializer
2061 .end_struct()
2062 .map_err(SerializeError::Backend)
2063 }
2064 }
2065 }
2066 DynValueKind::DateTime => {
2067 let dt = dynamic.as_datetime().ok_or_else(|| {
2068 SerializeError::Internal(Cow::Borrowed("dynamic datetime missing value"))
2069 })?;
2070 if tagged {
2071 self.serializer
2072 .dynamic_value_tag(DynamicValueTag::DateTime)
2073 .map_err(SerializeError::Backend)?;
2074 }
2075 let s = format_dyn_datetime(dt);
2076 self.serializer
2077 .scalar(ScalarValue::Str(Cow::Owned(s)))
2078 .map_err(SerializeError::Backend)
2079 }
2080 DynValueKind::QName | DynValueKind::Uuid => Err(SerializeError::Unsupported(
2081 Cow::Borrowed("dynamic QName/Uuid serialization is not supported"),
2082 )),
2083 }
2084 }
2085
2086 #[allow(unsafe_code)]
2087 fn serialize_via_proxy<'mem, 'facet>(
2088 &mut self,
2089 value: Peek<'mem, 'facet>,
2090 proxy_def: &'static facet_core::ProxyDef,
2091 ) -> Result<(), SerializeError<S::Error>> {
2092 let proxy_shape = proxy_def.shape;
2093 let proxy_layout = proxy_shape.layout.sized_layout().map_err(|_| {
2094 SerializeError::Unsupported(Cow::Borrowed("proxy type must be sized for serialization"))
2095 })?;
2096
2097 let proxy_uninit = facet_core::alloc_for_layout(proxy_layout);
2098 let convert_result = unsafe { (proxy_def.convert_out)(value.data(), proxy_uninit) };
2099
2100 let proxy_ptr = match convert_result {
2101 Ok(ptr) => ptr,
2102 Err(msg) => {
2103 unsafe { facet_core::dealloc_for_layout(proxy_uninit.assume_init(), proxy_layout) };
2104 return Err(SerializeError::Unsupported(Cow::Owned(msg)));
2105 }
2106 };
2107
2108 let proxy_peek = unsafe { Peek::unchecked_new(proxy_ptr.as_const(), proxy_shape) };
2109 let result = self.serialize_impl(proxy_peek);
2110
2111 unsafe {
2112 let _ = proxy_shape.call_drop_in_place(proxy_ptr);
2113 facet_core::dealloc_for_layout(proxy_ptr, proxy_layout);
2114 }
2115
2116 result
2117 }
2118}
2119
2120impl<E: Debug> std::error::Error for SerializeError<E> {}
2121
2122fn def_kind_name(def: &Def) -> &'static str {
2124 match def {
2125 Def::Undefined => "Undefined",
2126 Def::Scalar => "Scalar",
2127 Def::Map(_) => "Map",
2128 Def::Set(_) => "Set",
2129 Def::List(_) => "List",
2130 Def::Array(_) => "Array",
2131 Def::NdArray(_) => "NdArray",
2132 Def::Slice(_) => "Slice",
2133 Def::Option(_) => "Option",
2134 Def::Result(_) => "Result",
2135 Def::DynamicValue(_) => "DynamicValue",
2136 Def::Pointer(_) => "Pointer",
2137 _ => "Unknown",
2138 }
2139}
2140
2141pub fn serialize_root<'mem, 'facet, S>(
2143 serializer: &mut S,
2144 value: Peek<'mem, 'facet>,
2145) -> Result<(), SerializeError<S::Error>>
2146where
2147 S: FormatSerializer,
2148{
2149 let mut ctx = SerializeContext::new(serializer);
2150 ctx.serialize(value)
2151}
2152
2153fn sort_fields_if_needed<'mem, 'facet, S>(
2155 _serializer: &S,
2156 _fields: &mut alloc::vec::Vec<(facet_reflect::FieldItem, Peek<'mem, 'facet>)>,
2157) where
2158 S: FormatSerializer,
2159{
2160 }
2162
2163fn format_dyn_datetime(
2164 (year, month, day, hour, minute, second, nanos, kind): (
2165 i32,
2166 u8,
2167 u8,
2168 u8,
2169 u8,
2170 u8,
2171 u32,
2172 DynDateTimeKind,
2173 ),
2174) -> String {
2175 let mut out = String::new();
2176 match kind {
2177 DynDateTimeKind::Offset { offset_minutes } => {
2178 let _ = write!(
2179 out,
2180 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}",
2181 year, month, day, hour, minute, second
2182 );
2183 if nanos > 0 {
2184 let _ = write!(out, ".{:09}", nanos);
2185 }
2186 if offset_minutes == 0 {
2187 out.push('Z');
2188 } else {
2189 let sign = if offset_minutes >= 0 { '+' } else { '-' };
2190 let abs = offset_minutes.unsigned_abs();
2191 let _ = write!(out, "{}{:02}:{:02}", sign, abs / 60, abs % 60);
2192 }
2193 }
2194 DynDateTimeKind::LocalDateTime => {
2195 let _ = write!(
2196 out,
2197 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}",
2198 year, month, day, hour, minute, second
2199 );
2200 if nanos > 0 {
2201 let _ = write!(out, ".{:09}", nanos);
2202 }
2203 }
2204 DynDateTimeKind::LocalDate => {
2205 let _ = write!(out, "{:04}-{:02}-{:02}", year, month, day);
2206 }
2207 DynDateTimeKind::LocalTime => {
2208 let _ = write!(out, "{:02}:{:02}:{:02}", hour, minute, second);
2209 if nanos > 0 {
2210 let _ = write!(out, ".{:09}", nanos);
2211 }
2212 }
2213 }
2214 out
2215}
2216
2217fn serialize_numeric_enum<S>(
2218 serializer: &mut S,
2219 variant: &'static facet_core::Variant,
2220) -> Result<(), SerializeError<S::Error>>
2221where
2222 S: FormatSerializer,
2223{
2224 let discriminant = variant
2225 .discriminant
2226 .ok_or(SerializeError::Unsupported(Cow::Borrowed(
2227 "Enum without a discriminant",
2228 )))?;
2229 serializer
2230 .scalar(ScalarValue::I64(discriminant))
2231 .map_err(SerializeError::Backend)
2232}
2233
2234fn deref_if_pointer<'mem, 'facet>(peek: Peek<'mem, 'facet>) -> Peek<'mem, 'facet> {
2236 if let Ok(ptr) = peek.into_pointer()
2237 && let Some(target) = ptr.borrow_inner()
2238 {
2239 return deref_if_pointer(target);
2240 }
2241 peek
2242}
2243
2244pub fn serialize_value_with_shape<S>(
2270 serializer: &mut S,
2271 value: Peek<'_, '_>,
2272 target_shape: &'static Shape,
2273) -> Result<(), SerializeError<S::Error>>
2274where
2275 S: FormatSerializer,
2276{
2277 let dynamic = value.into_dynamic_value().map_err(|_| {
2278 SerializeError::Unsupported(Cow::Borrowed(
2279 "serialize_value_with_shape requires a DynamicValue type",
2280 ))
2281 })?;
2282
2283 serialize_dynamic_with_shape(serializer, dynamic, target_shape, value.shape())
2284}
2285
2286fn serialize_dynamic_with_shape<S>(
2287 serializer: &mut S,
2288 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2289 target_shape: &'static Shape,
2290 value_shape: &'static Shape,
2291) -> Result<(), SerializeError<S::Error>>
2292where
2293 S: FormatSerializer,
2294{
2295 use facet_core::{ListDef, OptionDef, ScalarType as CoreScalarType, Type, UserType};
2296
2297 if let Def::Pointer(ptr_def) = target_shape.def
2299 && let Some(pointee) = ptr_def.pointee
2300 {
2301 return serialize_dynamic_with_shape(serializer, dynamic, pointee, value_shape);
2302 }
2303
2304 if let Some(inner_shape) = target_shape.inner {
2306 if !matches!(
2308 target_shape.def,
2309 Def::List(_) | Def::Map(_) | Def::Set(_) | Def::Array(_)
2310 ) {
2311 return serialize_dynamic_with_shape(serializer, dynamic, inner_shape, value_shape);
2312 }
2313 }
2314
2315 if let Def::Option(OptionDef { t: inner_shape, .. }) = target_shape.def {
2317 return serialize_option_from_dynamic(serializer, dynamic, inner_shape, value_shape);
2318 }
2319
2320 if let Def::List(ListDef { t: item_shape, .. }) = target_shape.def {
2322 return serialize_list_from_dynamic(serializer, dynamic, item_shape, value_shape);
2323 }
2324
2325 if let Def::Array(array_def) = target_shape.def {
2327 return serialize_array_from_dynamic(serializer, dynamic, array_def.t, value_shape);
2328 }
2329
2330 if let Def::Map(map_def) = target_shape.def {
2332 return serialize_map_from_dynamic(serializer, dynamic, map_def.k, map_def.v, value_shape);
2333 }
2334
2335 if let Some(scalar_type) = CoreScalarType::try_from_shape(target_shape) {
2337 return serialize_scalar_from_dynamic(serializer, dynamic, scalar_type);
2338 }
2339
2340 match target_shape.ty {
2342 Type::User(UserType::Struct(struct_def)) => {
2343 serialize_struct_from_dynamic(serializer, dynamic, struct_def, value_shape)
2344 }
2345 Type::User(UserType::Enum(enum_def)) => {
2346 serialize_enum_from_dynamic(serializer, dynamic, enum_def, target_shape, value_shape)
2347 }
2348 _ => Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2349 "unsupported target shape for serialize_value_with_shape: {}",
2350 target_shape
2351 )))),
2352 }
2353}
2354
2355fn serialize_option_from_dynamic<S>(
2356 serializer: &mut S,
2357 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2358 inner_shape: &'static Shape,
2359 value_shape: &'static Shape,
2360) -> Result<(), SerializeError<S::Error>>
2361where
2362 S: FormatSerializer,
2363{
2364 if dynamic.kind() == DynValueKind::Null {
2365 serializer.serialize_none().map_err(SerializeError::Backend)
2366 } else {
2367 serializer
2368 .begin_option_some()
2369 .map_err(SerializeError::Backend)?;
2370 serialize_dynamic_with_shape(serializer, dynamic, inner_shape, value_shape)
2371 }
2372}
2373
2374fn serialize_list_from_dynamic<S>(
2375 serializer: &mut S,
2376 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2377 item_shape: &'static Shape,
2378 value_shape: &'static Shape,
2379) -> Result<(), SerializeError<S::Error>>
2380where
2381 S: FormatSerializer,
2382{
2383 let len = dynamic.array_len().ok_or_else(|| {
2384 SerializeError::Unsupported(Cow::Borrowed(
2385 "expected array value for list/vec target shape",
2386 ))
2387 })?;
2388
2389 serializer
2390 .begin_seq_with_len(len)
2391 .map_err(SerializeError::Backend)?;
2392
2393 if let Some(iter) = dynamic.array_iter() {
2394 for elem in iter {
2395 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2396 SerializeError::Internal(Cow::Borrowed("array element is not a dynamic value"))
2397 })?;
2398 serialize_dynamic_with_shape(serializer, elem_dyn, item_shape, value_shape)?;
2399 }
2400 }
2401
2402 serializer.end_seq().map_err(SerializeError::Backend)
2403}
2404
2405fn serialize_array_from_dynamic<S>(
2406 serializer: &mut S,
2407 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2408 item_shape: &'static Shape,
2409 value_shape: &'static Shape,
2410) -> Result<(), SerializeError<S::Error>>
2411where
2412 S: FormatSerializer,
2413{
2414 serializer.begin_seq().map_err(SerializeError::Backend)?;
2416
2417 if let Some(iter) = dynamic.array_iter() {
2418 for elem in iter {
2419 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2420 SerializeError::Internal(Cow::Borrowed("array element is not a dynamic value"))
2421 })?;
2422 serialize_dynamic_with_shape(serializer, elem_dyn, item_shape, value_shape)?;
2423 }
2424 }
2425
2426 serializer.end_seq().map_err(SerializeError::Backend)
2427}
2428
2429fn serialize_map_from_dynamic<S>(
2430 serializer: &mut S,
2431 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2432 key_shape: &'static Shape,
2433 value_shape_inner: &'static Shape,
2434 value_shape: &'static Shape,
2435) -> Result<(), SerializeError<S::Error>>
2436where
2437 S: FormatSerializer,
2438{
2439 let len = dynamic.object_len().ok_or_else(|| {
2440 SerializeError::Unsupported(Cow::Borrowed("expected object value for map target shape"))
2441 })?;
2442
2443 match serializer.map_encoding() {
2444 MapEncoding::Pairs => {
2445 serializer
2446 .begin_map_with_len(len)
2447 .map_err(SerializeError::Backend)?;
2448
2449 if let Some(iter) = dynamic.object_iter() {
2450 for (key, val) in iter {
2451 serialize_string_as_scalar(serializer, key, key_shape)?;
2453 let val_dyn = val.into_dynamic_value().map_err(|_| {
2455 SerializeError::Internal(Cow::Borrowed(
2456 "object value is not a dynamic value",
2457 ))
2458 })?;
2459 serialize_dynamic_with_shape(
2460 serializer,
2461 val_dyn,
2462 value_shape_inner,
2463 value_shape,
2464 )?;
2465 }
2466 }
2467
2468 serializer.end_map().map_err(SerializeError::Backend)
2469 }
2470 MapEncoding::Struct => {
2471 serializer.begin_struct().map_err(SerializeError::Backend)?;
2472
2473 if let Some(iter) = dynamic.object_iter() {
2474 for (key, val) in iter {
2475 serializer.field_key(key).map_err(SerializeError::Backend)?;
2476 let val_dyn = val.into_dynamic_value().map_err(|_| {
2477 SerializeError::Internal(Cow::Borrowed(
2478 "object value is not a dynamic value",
2479 ))
2480 })?;
2481 serialize_dynamic_with_shape(
2482 serializer,
2483 val_dyn,
2484 value_shape_inner,
2485 value_shape,
2486 )?;
2487 }
2488 }
2489
2490 serializer.end_struct().map_err(SerializeError::Backend)
2491 }
2492 }
2493}
2494
2495fn serialize_string_as_scalar<S>(
2496 serializer: &mut S,
2497 s: &str,
2498 _key_shape: &'static Shape,
2499) -> Result<(), SerializeError<S::Error>>
2500where
2501 S: FormatSerializer,
2502{
2503 serializer
2506 .scalar(ScalarValue::Str(Cow::Borrowed(s)))
2507 .map_err(SerializeError::Backend)
2508}
2509
2510fn serialize_scalar_from_dynamic<S>(
2511 serializer: &mut S,
2512 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2513 scalar_type: facet_core::ScalarType,
2514) -> Result<(), SerializeError<S::Error>>
2515where
2516 S: FormatSerializer,
2517{
2518 use facet_core::ScalarType as ST;
2519
2520 match scalar_type {
2521 ST::Unit => serializer
2522 .scalar(ScalarValue::Null)
2523 .map_err(SerializeError::Backend),
2524 ST::Bool => {
2525 let v = dynamic
2526 .as_bool()
2527 .ok_or_else(|| SerializeError::Unsupported(Cow::Borrowed("expected bool value")))?;
2528 serializer
2529 .scalar(ScalarValue::Bool(v))
2530 .map_err(SerializeError::Backend)
2531 }
2532 ST::Char => {
2533 let s = dynamic.as_str().ok_or_else(|| {
2534 SerializeError::Unsupported(Cow::Borrowed("expected string value for char"))
2535 })?;
2536 let c = s.chars().next().ok_or_else(|| {
2537 SerializeError::Unsupported(Cow::Borrowed("expected non-empty string for char"))
2538 })?;
2539 serializer
2540 .scalar(ScalarValue::Char(c))
2541 .map_err(SerializeError::Backend)
2542 }
2543 ST::Str | ST::String | ST::CowStr => {
2544 let s = dynamic.as_str().ok_or_else(|| {
2545 SerializeError::Unsupported(Cow::Borrowed("expected string value"))
2546 })?;
2547 serializer
2548 .scalar(ScalarValue::Str(Cow::Borrowed(s)))
2549 .map_err(SerializeError::Backend)
2550 }
2551 ST::U8 | ST::U16 | ST::U32 | ST::U64 | ST::USize => {
2552 let n = dynamic.as_u64().ok_or_else(|| {
2553 SerializeError::Unsupported(Cow::Borrowed("expected unsigned integer value"))
2554 })?;
2555 serializer
2556 .scalar(ScalarValue::U64(n))
2557 .map_err(SerializeError::Backend)
2558 }
2559 ST::U128 => {
2560 let n = dynamic.as_u64().ok_or_else(|| {
2561 SerializeError::Unsupported(Cow::Borrowed("expected unsigned integer value"))
2562 })?;
2563 serializer
2564 .scalar(ScalarValue::U128(n as u128))
2565 .map_err(SerializeError::Backend)
2566 }
2567 ST::I8 | ST::I16 | ST::I32 | ST::I64 | ST::ISize => {
2568 let n = dynamic.as_i64().ok_or_else(|| {
2569 SerializeError::Unsupported(Cow::Borrowed("expected signed integer value"))
2570 })?;
2571 serializer
2572 .scalar(ScalarValue::I64(n))
2573 .map_err(SerializeError::Backend)
2574 }
2575 ST::I128 => {
2576 let n = dynamic.as_i64().ok_or_else(|| {
2577 SerializeError::Unsupported(Cow::Borrowed("expected signed integer value"))
2578 })?;
2579 serializer
2580 .scalar(ScalarValue::I128(n as i128))
2581 .map_err(SerializeError::Backend)
2582 }
2583 ST::F32 | ST::F64 => {
2584 let n = dynamic.as_f64().ok_or_else(|| {
2585 SerializeError::Unsupported(Cow::Borrowed("expected float value"))
2586 })?;
2587 serializer
2588 .scalar(ScalarValue::F64(n))
2589 .map_err(SerializeError::Backend)
2590 }
2591 _ => Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2592 "unsupported scalar type: {:?}",
2593 scalar_type
2594 )))),
2595 }
2596}
2597
2598fn serialize_struct_from_dynamic<S>(
2599 serializer: &mut S,
2600 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2601 struct_def: facet_core::StructType,
2602 value_shape: &'static Shape,
2603) -> Result<(), SerializeError<S::Error>>
2604where
2605 S: FormatSerializer,
2606{
2607 let is_tuple = matches!(struct_def.kind, StructKind::Tuple | StructKind::TupleStruct);
2608
2609 if is_tuple {
2610 serializer.begin_seq().map_err(SerializeError::Backend)?;
2612
2613 let iter = dynamic.array_iter().ok_or_else(|| {
2614 SerializeError::Unsupported(Cow::Borrowed("expected array value for tuple"))
2615 })?;
2616
2617 for (field, elem) in struct_def.fields.iter().zip(iter) {
2618 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2619 SerializeError::Internal(Cow::Borrowed("tuple element is not a dynamic value"))
2620 })?;
2621 serialize_dynamic_with_shape(serializer, elem_dyn, field.shape(), value_shape)?;
2622 }
2623
2624 serializer.end_seq().map_err(SerializeError::Backend)
2625 } else {
2626 let field_mode = serializer.struct_field_mode();
2628
2629 serializer.begin_struct().map_err(SerializeError::Backend)?;
2630
2631 for field in struct_def.fields {
2632 if field.is_metadata() {
2634 continue;
2635 }
2636
2637 let field_name = field.name;
2638 let field_value = dynamic.object_get(field_name).ok_or_else(|| {
2639 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2640 "missing field '{}' in object",
2641 field_name
2642 )))
2643 })?;
2644
2645 if field_mode == StructFieldMode::Named {
2646 serializer
2647 .field_key(field_name)
2648 .map_err(SerializeError::Backend)?;
2649 }
2650
2651 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
2652 SerializeError::Internal(Cow::Borrowed("field value is not a dynamic value"))
2653 })?;
2654 serialize_dynamic_with_shape(serializer, field_dyn, field.shape(), value_shape)?;
2655 }
2656
2657 serializer.end_struct().map_err(SerializeError::Backend)
2658 }
2659}
2660
2661fn serialize_enum_from_dynamic<S>(
2662 serializer: &mut S,
2663 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2664 enum_def: facet_core::EnumType,
2665 target_shape: &'static Shape,
2666 value_shape: &'static Shape,
2667) -> Result<(), SerializeError<S::Error>>
2668where
2669 S: FormatSerializer,
2670{
2671 let use_index = serializer.enum_variant_encoding() == EnumVariantEncoding::Index;
2677
2678 match dynamic.kind() {
2679 DynValueKind::String => {
2681 let variant_name = dynamic.as_str().ok_or_else(|| {
2682 SerializeError::Internal(Cow::Borrowed("expected string for unit variant"))
2683 })?;
2684
2685 let (variant_index, variant) = enum_def
2686 .variants
2687 .iter()
2688 .enumerate()
2689 .find(|(_, v)| v.effective_name() == variant_name)
2690 .ok_or_else(|| {
2691 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2692 "unknown variant '{}'",
2693 variant_name
2694 )))
2695 })?;
2696
2697 if use_index {
2698 serializer
2699 .begin_enum_variant(variant_index, variant.effective_name())
2700 .map_err(SerializeError::Backend)?;
2701 Ok(())
2703 } else {
2704 serializer
2705 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
2706 .map_err(SerializeError::Backend)
2707 }
2708 }
2709
2710 DynValueKind::Object => {
2712 let obj_len = dynamic.object_len().unwrap_or(0);
2714 if obj_len != 1 {
2715 return Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2716 "expected single-key object for enum variant, got {} keys",
2717 obj_len
2718 ))));
2719 }
2720
2721 let (variant_name, payload) = dynamic.object_get_entry(0).ok_or_else(|| {
2722 SerializeError::Internal(Cow::Borrowed("expected object entry for enum variant"))
2723 })?;
2724
2725 let (variant_index, variant) = enum_def
2726 .variants
2727 .iter()
2728 .enumerate()
2729 .find(|(_, v)| v.effective_name() == variant_name)
2730 .ok_or_else(|| {
2731 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2732 "unknown variant '{}'",
2733 variant_name
2734 )))
2735 })?;
2736
2737 let payload_dyn = payload.into_dynamic_value().map_err(|_| {
2738 SerializeError::Internal(Cow::Borrowed("variant payload is not a dynamic value"))
2739 })?;
2740
2741 if use_index {
2742 serializer
2743 .begin_enum_variant(variant_index, variant.effective_name())
2744 .map_err(SerializeError::Backend)?;
2745
2746 match variant.data.kind {
2748 StructKind::Unit => {
2749 }
2751 StructKind::TupleStruct | StructKind::Tuple => {
2752 if variant.data.fields.len() == 1 {
2753 serialize_dynamic_with_shape(
2755 serializer,
2756 payload_dyn,
2757 variant.data.fields[0].shape(),
2758 value_shape,
2759 )?;
2760 } else {
2761 let iter = payload_dyn.array_iter().ok_or_else(|| {
2763 SerializeError::Unsupported(Cow::Borrowed(
2764 "expected array for tuple variant payload",
2765 ))
2766 })?;
2767
2768 for (field, elem) in variant.data.fields.iter().zip(iter) {
2769 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2770 SerializeError::Internal(Cow::Borrowed(
2771 "tuple element is not a dynamic value",
2772 ))
2773 })?;
2774 serialize_dynamic_with_shape(
2775 serializer,
2776 elem_dyn,
2777 field.shape(),
2778 value_shape,
2779 )?;
2780 }
2781 }
2782 }
2783 StructKind::Struct => {
2784 for field in variant.data.fields {
2786 let field_value =
2787 payload_dyn.object_get(field.name).ok_or_else(|| {
2788 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2789 "missing field '{}' in struct variant",
2790 field.name
2791 )))
2792 })?;
2793 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
2794 SerializeError::Internal(Cow::Borrowed(
2795 "field value is not a dynamic value",
2796 ))
2797 })?;
2798 serialize_dynamic_with_shape(
2799 serializer,
2800 field_dyn,
2801 field.shape(),
2802 value_shape,
2803 )?;
2804 }
2805 }
2806 }
2807
2808 Ok(())
2809 } else {
2810 serializer.begin_struct().map_err(SerializeError::Backend)?;
2812 serializer
2813 .field_key(variant.effective_name())
2814 .map_err(SerializeError::Backend)?;
2815
2816 match variant.data.kind {
2817 StructKind::Unit => {
2818 serializer
2819 .scalar(ScalarValue::Null)
2820 .map_err(SerializeError::Backend)?;
2821 }
2822 StructKind::TupleStruct | StructKind::Tuple => {
2823 if variant.data.fields.len() == 1 {
2824 serialize_dynamic_with_shape(
2825 serializer,
2826 payload_dyn,
2827 variant.data.fields[0].shape(),
2828 value_shape,
2829 )?;
2830 } else {
2831 serializer.begin_seq().map_err(SerializeError::Backend)?;
2832 let iter = payload_dyn.array_iter().ok_or_else(|| {
2833 SerializeError::Unsupported(Cow::Borrowed(
2834 "expected array for tuple variant",
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 "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 serializer.end_seq().map_err(SerializeError::Backend)?;
2851 }
2852 }
2853 StructKind::Struct => {
2854 serializer.begin_struct().map_err(SerializeError::Backend)?;
2855 for field in variant.data.fields {
2856 let field_value =
2857 payload_dyn.object_get(field.name).ok_or_else(|| {
2858 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2859 "missing field '{}'",
2860 field.name
2861 )))
2862 })?;
2863 serializer
2864 .field_key(field.name)
2865 .map_err(SerializeError::Backend)?;
2866 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
2867 SerializeError::Internal(Cow::Borrowed(
2868 "field is not a dynamic value",
2869 ))
2870 })?;
2871 serialize_dynamic_with_shape(
2872 serializer,
2873 field_dyn,
2874 field.shape(),
2875 value_shape,
2876 )?;
2877 }
2878 serializer.end_struct().map_err(SerializeError::Backend)?;
2879 }
2880 }
2881
2882 serializer.end_struct().map_err(SerializeError::Backend)
2883 }
2884 }
2885
2886 DynValueKind::Null => {
2888 if let Some((variant_index, variant)) = enum_def
2891 .variants
2892 .iter()
2893 .enumerate()
2894 .find(|(_, v)| v.name.eq_ignore_ascii_case("null") || v.name == "None")
2895 {
2896 if use_index {
2897 serializer
2898 .begin_enum_variant(variant_index, variant.effective_name())
2899 .map_err(SerializeError::Backend)?;
2900 Ok(())
2901 } else {
2902 serializer
2903 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
2904 .map_err(SerializeError::Backend)
2905 }
2906 } else {
2907 Err(SerializeError::Unsupported(Cow::Borrowed(
2908 "null value for enum without null/None variant",
2909 )))
2910 }
2911 }
2912
2913 _ => {
2914 let _ = target_shape; Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2918 "unsupported dynamic value kind {:?} for enum serialization",
2919 dynamic.kind()
2920 ))))
2921 }
2922 }
2923}