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