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::{Def, DynDateTimeKind, DynValueKind, ScalarType, Shape, StructKind, Type};
9use facet_reflect::{HasFields as _, Peek, ReflectError};
10
11use crate::ScalarValue;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
15pub enum FieldOrdering {
16 #[default]
18 Declaration,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
23pub enum StructFieldMode {
24 #[default]
26 Named,
27 Unnamed,
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
33pub enum MapEncoding {
34 #[default]
36 Struct,
37 Pairs,
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
43pub enum EnumVariantEncoding {
44 #[default]
46 Tagged,
47 Index,
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
53pub enum DynamicValueEncoding {
54 #[default]
56 SelfDescribing,
57 Tagged,
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
63pub enum DynamicValueTag {
64 Null,
66 Bool,
68 I64,
70 U64,
72 F64,
74 String,
76 Bytes,
78 Array,
80 Object,
82 DateTime,
84}
85
86pub trait FormatSerializer {
91 type Error: Debug;
93
94 fn begin_struct(&mut self) -> Result<(), Self::Error>;
96 fn field_key(&mut self, key: &str) -> Result<(), Self::Error>;
98 fn emit_field_key(&mut self, key: &crate::FieldKey<'_>) -> Result<(), Self::Error> {
106 let name = key.name.as_deref().unwrap_or("");
108 self.field_key(name)
109 }
110 fn end_struct(&mut self) -> Result<(), Self::Error>;
112
113 fn begin_seq(&mut self) -> Result<(), Self::Error>;
115 fn end_seq(&mut self) -> Result<(), Self::Error>;
117
118 fn scalar(&mut self, scalar: ScalarValue<'_>) -> Result<(), Self::Error>;
120
121 fn field_metadata(&mut self, _field: &facet_reflect::FieldItem) -> Result<(), Self::Error> {
124 Ok(())
125 }
126
127 fn field_metadata_with_value(
138 &mut self,
139 _field: &facet_reflect::FieldItem,
140 _value: Peek<'_, '_>,
141 ) -> Result<bool, Self::Error> {
142 Ok(false)
143 }
144
145 fn struct_metadata(&mut self, _shape: &facet_core::Shape) -> Result<(), Self::Error> {
148 Ok(())
149 }
150
151 fn variant_metadata(
154 &mut self,
155 _variant: &'static facet_core::Variant,
156 ) -> Result<(), Self::Error> {
157 Ok(())
158 }
159
160 fn serialize_metadata_container(
182 &mut self,
183 _container: &facet_reflect::PeekStruct<'_, '_>,
184 ) -> Result<bool, Self::Error> {
185 Ok(false)
186 }
187
188 fn preferred_field_order(&self) -> FieldOrdering {
191 FieldOrdering::Declaration
192 }
193
194 fn struct_field_mode(&self) -> StructFieldMode {
196 StructFieldMode::Named
197 }
198
199 fn map_encoding(&self) -> MapEncoding {
201 MapEncoding::Struct
202 }
203
204 fn enum_variant_encoding(&self) -> EnumVariantEncoding {
206 EnumVariantEncoding::Tagged
207 }
208
209 fn is_self_describing(&self) -> bool {
217 true
218 }
219
220 fn dynamic_value_encoding(&self) -> DynamicValueEncoding {
222 DynamicValueEncoding::SelfDescribing
223 }
224
225 fn raw_serialize_shape(&self) -> Option<&'static facet_core::Shape> {
231 None
232 }
233
234 fn raw_scalar(&mut self, content: &str) -> Result<(), Self::Error> {
239 self.scalar(ScalarValue::Str(Cow::Borrowed(content)))
241 }
242
243 fn serialize_opaque_scalar(
247 &mut self,
248 _shape: &'static facet_core::Shape,
249 _value: Peek<'_, '_>,
250 ) -> Result<bool, Self::Error> {
251 Ok(false)
252 }
253
254 fn dynamic_value_tag(&mut self, _tag: DynamicValueTag) -> Result<(), Self::Error> {
259 Ok(())
260 }
261
262 fn begin_seq_with_len(&mut self, _len: usize) -> Result<(), Self::Error> {
279 self.begin_seq()
280 }
281
282 fn begin_map_with_len(&mut self, _len: usize) -> Result<(), Self::Error> {
286 self.begin_struct()
287 }
288
289 fn end_map(&mut self) -> Result<(), Self::Error> {
293 self.end_struct()
294 }
295
296 fn serialize_map_key(&mut self, _key: Peek<'_, '_>) -> Result<bool, Self::Error> {
307 Ok(false)
308 }
309
310 fn typed_scalar(
320 &mut self,
321 scalar_type: ScalarType,
322 value: Peek<'_, '_>,
323 ) -> Result<(), Self::Error> {
324 let scalar = match scalar_type {
326 ScalarType::Unit => ScalarValue::Null,
327 ScalarType::Bool => ScalarValue::Bool(*value.get::<bool>().unwrap()),
328 ScalarType::Char => ScalarValue::Char(*value.get::<char>().unwrap()),
329 ScalarType::Str | ScalarType::String | ScalarType::CowStr => {
330 ScalarValue::Str(Cow::Borrowed(value.as_str().unwrap()))
331 }
332 ScalarType::F32 => ScalarValue::F64(*value.get::<f32>().unwrap() as f64),
333 ScalarType::F64 => ScalarValue::F64(*value.get::<f64>().unwrap()),
334 ScalarType::U8 => ScalarValue::U64(*value.get::<u8>().unwrap() as u64),
335 ScalarType::U16 => ScalarValue::U64(*value.get::<u16>().unwrap() as u64),
336 ScalarType::U32 => ScalarValue::U64(*value.get::<u32>().unwrap() as u64),
337 ScalarType::U64 => ScalarValue::U64(*value.get::<u64>().unwrap()),
338 ScalarType::U128 => {
339 let n = *value.get::<u128>().unwrap();
340 ScalarValue::Str(Cow::Owned(alloc::string::ToString::to_string(&n)))
341 }
342 ScalarType::USize => ScalarValue::U64(*value.get::<usize>().unwrap() as u64),
343 ScalarType::I8 => ScalarValue::I64(*value.get::<i8>().unwrap() as i64),
344 ScalarType::I16 => ScalarValue::I64(*value.get::<i16>().unwrap() as i64),
345 ScalarType::I32 => ScalarValue::I64(*value.get::<i32>().unwrap() as i64),
346 ScalarType::I64 => ScalarValue::I64(*value.get::<i64>().unwrap()),
347 ScalarType::I128 => {
348 let n = *value.get::<i128>().unwrap();
349 ScalarValue::Str(Cow::Owned(alloc::string::ToString::to_string(&n)))
350 }
351 ScalarType::ISize => ScalarValue::I64(*value.get::<isize>().unwrap() as i64),
352 #[cfg(feature = "net")]
353 ScalarType::IpAddr => {
354 let addr = *value.get::<core::net::IpAddr>().unwrap();
355 ScalarValue::Str(Cow::Owned(alloc::string::ToString::to_string(&addr)))
356 }
357 #[cfg(feature = "net")]
358 ScalarType::Ipv4Addr => {
359 let addr = *value.get::<core::net::Ipv4Addr>().unwrap();
360 ScalarValue::Str(Cow::Owned(alloc::string::ToString::to_string(&addr)))
361 }
362 #[cfg(feature = "net")]
363 ScalarType::Ipv6Addr => {
364 let addr = *value.get::<core::net::Ipv6Addr>().unwrap();
365 ScalarValue::Str(Cow::Owned(alloc::string::ToString::to_string(&addr)))
366 }
367 #[cfg(feature = "net")]
368 ScalarType::SocketAddr => {
369 let addr = *value.get::<core::net::SocketAddr>().unwrap();
370 ScalarValue::Str(Cow::Owned(alloc::string::ToString::to_string(&addr)))
371 }
372 _ => {
373 if let Some(s) = value.as_str() {
375 ScalarValue::Str(Cow::Borrowed(s))
376 } else {
377 ScalarValue::Null
378 }
379 }
380 };
381 self.scalar(scalar)
382 }
383
384 fn begin_option_some(&mut self) -> Result<(), Self::Error> {
391 Ok(())
392 }
393
394 fn serialize_none(&mut self) -> Result<(), Self::Error> {
401 self.scalar(ScalarValue::Null)
402 }
403
404 fn begin_enum_variant(
414 &mut self,
415 _variant_index: usize,
416 _variant_name: &'static str,
417 ) -> Result<(), Self::Error> {
418 Ok(())
419 }
420
421 fn write_variant_tag(&mut self, _variant_name: &str) -> Result<bool, Self::Error> {
435 Ok(false)
436 }
437
438 fn begin_struct_after_tag(&mut self) -> Result<(), Self::Error> {
445 self.begin_struct()
446 }
447
448 fn begin_seq_after_tag(&mut self) -> Result<(), Self::Error> {
455 self.begin_seq()
456 }
457
458 fn serialize_byte_sequence(&mut self, _bytes: &[u8]) -> Result<bool, Self::Error> {
471 Ok(false)
473 }
474
475 fn serialize_byte_array(&mut self, _bytes: &[u8]) -> Result<bool, Self::Error> {
482 Ok(false)
484 }
485
486 fn format_namespace(&self) -> Option<&'static str> {
498 None
499 }
500}
501
502#[derive(Debug)]
504pub enum SerializeError<E: Debug> {
505 Backend(E),
507 Reflect(ReflectError),
509 Unsupported(Cow<'static, str>),
511 Internal(Cow<'static, str>),
513}
514
515impl<E: Debug> core::fmt::Display for SerializeError<E> {
516 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
517 match self {
518 SerializeError::Backend(_) => f.write_str("format serializer error"),
519 SerializeError::Reflect(err) => write!(f, "{err}"),
520 SerializeError::Unsupported(msg) => f.write_str(msg.as_ref()),
521 SerializeError::Internal(msg) => f.write_str(msg.as_ref()),
522 }
523 }
524}
525
526impl<E: Debug> std::error::Error for SerializeError<E> {}
527
528pub fn serialize_root<'mem, 'facet, S>(
530 serializer: &mut S,
531 value: Peek<'mem, 'facet>,
532) -> Result<(), SerializeError<S::Error>>
533where
534 S: FormatSerializer,
535{
536 shared_serialize(serializer, value)
537}
538
539fn sort_fields_if_needed<'mem, 'facet, S>(
541 _serializer: &S,
542 _fields: &mut alloc::vec::Vec<(facet_reflect::FieldItem, Peek<'mem, 'facet>)>,
543) where
544 S: FormatSerializer,
545{
546 }
548
549fn shared_serialize<'mem, 'facet, S>(
550 serializer: &mut S,
551 value: Peek<'mem, 'facet>,
552) -> Result<(), SerializeError<S::Error>>
553where
554 S: FormatSerializer,
555{
556 let value = deref_if_pointer(value);
558
559 if serializer.raw_serialize_shape() == Some(value.shape()) {
562 if let Ok(struct_) = value.into_struct()
566 && let Some((_field_item, inner_value)) = struct_.fields_for_binary_serialize().next()
567 && let Some(s) = inner_value.as_str()
568 {
569 return serializer.raw_scalar(s).map_err(SerializeError::Backend);
570 }
571 return Err(SerializeError::Unsupported(Cow::Borrowed(
574 "raw capture type matched but could not extract inner string",
575 )));
576 }
577
578 if serializer
579 .serialize_opaque_scalar(value.shape(), value)
580 .map_err(SerializeError::Backend)?
581 {
582 return Ok(());
583 }
584
585 let value = value.innermost_peek();
586
587 if value.shape().is_metadata_container()
591 && let Ok(struct_) = value.into_struct()
592 {
593 if serializer
595 .serialize_metadata_container(&struct_)
596 .map_err(SerializeError::Backend)?
597 {
598 return Ok(());
599 }
600 for (field, field_value) in struct_.fields() {
602 if !field.is_metadata() {
603 return shared_serialize(serializer, field_value);
604 }
605 }
606 }
607
608 if let Some(proxy_def) = value.shape().effective_proxy(serializer.format_namespace()) {
611 return serialize_via_proxy(serializer, value, proxy_def);
612 }
613
614 if let Some(scalar_type) = value.scalar_type() {
616 return serializer
617 .typed_scalar(scalar_type, value)
618 .map_err(SerializeError::Backend);
619 }
620
621 if matches!(value.shape().def, Def::Scalar) && value.shape().vtable.has_display() {
624 use alloc::string::ToString;
625 let formatted = value.to_string();
626 return serializer
627 .scalar(ScalarValue::Str(Cow::Owned(formatted)))
628 .map_err(SerializeError::Backend);
629 }
630
631 if let Ok(opt) = value.into_option() {
633 return match opt.value() {
634 Some(inner) => {
635 serializer
636 .begin_option_some()
637 .map_err(SerializeError::Backend)?;
638 shared_serialize(serializer, inner)
639 }
640 None => serializer.serialize_none().map_err(SerializeError::Backend),
641 };
642 }
643
644 if let Ok(result) = value.into_result() {
645 let (variant_index, variant_name, inner) = if result.is_ok() {
646 (
647 0,
648 "Ok",
649 result.ok().ok_or(SerializeError::Internal(Cow::Borrowed(
650 "result reported Ok but value was missing",
651 )))?,
652 )
653 } else {
654 (
655 1,
656 "Err",
657 result.err().ok_or(SerializeError::Internal(Cow::Borrowed(
658 "result reported Err but value was missing",
659 )))?,
660 )
661 };
662
663 if serializer.enum_variant_encoding() == EnumVariantEncoding::Index {
664 serializer
665 .begin_enum_variant(variant_index, variant_name)
666 .map_err(SerializeError::Backend)?;
667 return shared_serialize(serializer, inner);
668 }
669
670 serializer.begin_struct().map_err(SerializeError::Backend)?;
672 serializer
673 .field_key(variant_name)
674 .map_err(SerializeError::Backend)?;
675 shared_serialize(serializer, inner)?;
676 serializer.end_struct().map_err(SerializeError::Backend)?;
677 return Ok(());
678 }
679
680 if let Ok(dynamic) = value.into_dynamic_value() {
681 return serialize_dynamic_value(serializer, dynamic);
682 }
683
684 match value.shape().def {
685 facet_core::Def::List(_) | facet_core::Def::Array(_) | facet_core::Def::Slice(_) => {
686 let list = value.into_list_like().map_err(SerializeError::Reflect)?;
687 let len = list.len();
688
689 if let Some(bytes) = list.as_bytes() {
691 let handled = match value.shape().def {
692 facet_core::Def::Array(_) => serializer
694 .serialize_byte_array(bytes)
695 .map_err(SerializeError::Backend)?,
696 _ => serializer
698 .serialize_byte_sequence(bytes)
699 .map_err(SerializeError::Backend)?,
700 };
701 if handled {
702 return Ok(());
703 }
704 }
705 match value.shape().def {
708 facet_core::Def::Array(_) => {
709 serializer.begin_seq().map_err(SerializeError::Backend)?
710 }
711 _ => serializer
712 .begin_seq_with_len(len)
713 .map_err(SerializeError::Backend)?,
714 };
715 for item in list.iter() {
716 shared_serialize(serializer, item)?;
717 }
718 serializer.end_seq().map_err(SerializeError::Backend)?;
719 return Ok(());
720 }
721 _ => {}
722 }
723
724 if let Ok(map) = value.into_map() {
725 let len = map.len();
726 match serializer.map_encoding() {
727 MapEncoding::Pairs => {
728 serializer
729 .begin_map_with_len(len)
730 .map_err(SerializeError::Backend)?;
731 for (key, val) in map.iter() {
732 shared_serialize(serializer, key)?;
733 shared_serialize(serializer, val)?;
734 }
735 serializer.end_map().map_err(SerializeError::Backend)?;
736 }
737 MapEncoding::Struct => {
738 serializer.begin_struct().map_err(SerializeError::Backend)?;
739 for (key, val) in map.iter() {
740 if !serializer
742 .serialize_map_key(key)
743 .map_err(SerializeError::Backend)?
744 {
745 let key_str = if let Some(s) = key.as_str() {
747 Cow::Borrowed(s)
748 } else {
749 Cow::Owned(alloc::format!("{}", key))
751 };
752 serializer
753 .field_key(&key_str)
754 .map_err(SerializeError::Backend)?;
755 }
756 shared_serialize(serializer, val)?;
757 }
758 serializer.end_struct().map_err(SerializeError::Backend)?;
759 }
760 }
761 return Ok(());
762 }
763
764 if let Ok(set) = value.into_set() {
765 let len = set.len();
767 serializer
768 .begin_seq_with_len(len)
769 .map_err(SerializeError::Backend)?;
770 for item in set.iter() {
771 shared_serialize(serializer, item)?;
772 }
773 serializer.end_seq().map_err(SerializeError::Backend)?;
774 return Ok(());
775 }
776
777 if let Ok(struct_) = value.into_struct() {
778 let kind = struct_.ty().kind;
779 let field_mode = serializer.struct_field_mode();
780
781 if kind == StructKind::Tuple || kind == StructKind::TupleStruct {
782 let fields: alloc::vec::Vec<_> = struct_.fields_for_binary_serialize().collect();
785 let is_transparent = value.shape().is_transparent() && fields.len() == 1;
786
787 if is_transparent {
788 let (field_item, field_value) = &fields[0];
790 if let Some(proxy_def) = field_item
791 .field
792 .and_then(|f| f.effective_proxy(serializer.format_namespace()))
793 {
794 serialize_via_proxy(serializer, *field_value, proxy_def)?;
795 } else {
796 shared_serialize(serializer, *field_value)?;
797 }
798 } else {
799 serializer.begin_seq().map_err(SerializeError::Backend)?;
802 for (field_item, field_value) in fields {
803 if let Some(proxy_def) = field_item
805 .field
806 .and_then(|f| f.effective_proxy(serializer.format_namespace()))
807 {
808 serialize_via_proxy(serializer, field_value, proxy_def)?;
809 } else {
810 shared_serialize(serializer, field_value)?;
811 }
812 }
813 serializer.end_seq().map_err(SerializeError::Backend)?;
814 }
815 } else {
816 serializer
818 .struct_metadata(value.shape())
819 .map_err(SerializeError::Backend)?;
820 serializer.begin_struct().map_err(SerializeError::Backend)?;
821
822 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
826 struct_.fields_for_binary_serialize().collect()
827 } else {
828 struct_.fields_for_serialize().collect()
829 };
830
831 sort_fields_if_needed(serializer, &mut fields);
832
833 for (field_item, field_value) in fields {
834 if field_item.flattened
837 && let Some(field) = field_item.field
838 && let shape = field.shape()
839 && let Some(tag_key) = shape.get_tag_attr()
840 && shape.get_content_attr().is_none()
841 {
842 let variant_name = field_item.effective_name();
844
845 if field_mode == StructFieldMode::Named {
847 serializer
848 .field_key(tag_key)
849 .map_err(SerializeError::Backend)?;
850 }
851 serializer
852 .scalar(ScalarValue::Str(Cow::Borrowed(variant_name)))
853 .map_err(SerializeError::Backend)?;
854
855 if let Ok(inner_struct) = field_value.into_struct() {
859 for (inner_item, inner_value) in inner_struct.fields_for_serialize() {
861 if field_mode == StructFieldMode::Named {
862 serializer
863 .field_key(inner_item.effective_name())
864 .map_err(SerializeError::Backend)?;
865 }
866 if let Some(proxy_def) = inner_item
867 .field
868 .and_then(|f| f.effective_proxy(serializer.format_namespace()))
869 {
870 serialize_via_proxy(serializer, inner_value, proxy_def)?;
871 } else {
872 shared_serialize(serializer, inner_value)?;
873 }
874 }
875 } else if let Ok(enum_peek) = field_value.into_enum() {
876 for (inner_item, inner_value) in enum_peek.fields_for_serialize() {
878 if field_mode == StructFieldMode::Named {
879 serializer
880 .field_key(inner_item.effective_name())
881 .map_err(SerializeError::Backend)?;
882 }
883 if let Some(proxy_def) = inner_item
884 .field
885 .and_then(|f| f.effective_proxy(serializer.format_namespace()))
886 {
887 serialize_via_proxy(serializer, inner_value, proxy_def)?;
888 } else {
889 shared_serialize(serializer, inner_value)?;
890 }
891 }
892 } else if matches!(field_value.shape().ty, Type::Primitive(_)) {
893 return Err(SerializeError::Unsupported(
898 "internally-tagged enum with scalar newtype payload cannot be \
899 flattened; use #[facet(content = \"...\")] for adjacently-tagged \
900 representation"
901 .into(),
902 ));
903 }
904 continue;
906 }
907
908 let key_written = serializer
910 .field_metadata_with_value(&field_item, field_value)
911 .map_err(SerializeError::Backend)?;
912 if !key_written {
913 serializer
914 .field_metadata(&field_item)
915 .map_err(SerializeError::Backend)?;
916 if field_mode == StructFieldMode::Named {
917 serializer
918 .field_key(field_item.effective_name())
919 .map_err(SerializeError::Backend)?;
920 }
921 }
922 if let Some(proxy_def) = field_item
924 .field
925 .and_then(|f| f.effective_proxy(serializer.format_namespace()))
926 {
927 serialize_via_proxy(serializer, field_value, proxy_def)?;
928 } else {
929 shared_serialize(serializer, field_value)?;
930 }
931 }
932 serializer.end_struct().map_err(SerializeError::Backend)?;
933 }
934 return Ok(());
935 }
936
937 if let Ok(enum_) = value.into_enum() {
938 let variant = enum_.active_variant().map_err(|_| {
939 SerializeError::Unsupported(Cow::Borrowed("opaque enum layout is unsupported"))
940 })?;
941
942 serializer
944 .variant_metadata(variant)
945 .map_err(SerializeError::Backend)?;
946
947 if serializer.enum_variant_encoding() == EnumVariantEncoding::Index {
948 let variant_index = enum_.variant_index().map_err(|_| {
949 SerializeError::Unsupported(Cow::Borrowed("opaque enum layout is unsupported"))
950 })?;
951 serializer
952 .begin_enum_variant(variant_index, variant.name)
953 .map_err(SerializeError::Backend)?;
954
955 match variant.data.kind {
956 StructKind::Unit => return Ok(()),
957 StructKind::TupleStruct | StructKind::Tuple | StructKind::Struct => {
958 for (field_item, field_value) in enum_.fields_for_binary_serialize() {
961 if let Some(proxy_def) = field_item
962 .field
963 .and_then(|f| f.effective_proxy(serializer.format_namespace()))
964 {
965 serialize_via_proxy(serializer, field_value, proxy_def)?;
966 } else {
967 shared_serialize(serializer, field_value)?;
968 }
969 }
970 return Ok(());
971 }
972 }
973 }
974
975 let numeric = value.shape().is_numeric();
976 let untagged = value.shape().is_untagged();
977 let tag = value.shape().get_tag_attr();
978 let content = value.shape().get_content_attr();
979
980 if numeric {
981 return serialize_numeric_enum(serializer, variant);
982 }
983 if untagged {
984 return serialize_untagged_enum(serializer, enum_, variant);
985 }
986
987 match (tag, content) {
988 (Some(tag_key), None) => {
989 serializer.begin_struct().map_err(SerializeError::Backend)?;
991 serializer
992 .field_key(tag_key)
993 .map_err(SerializeError::Backend)?;
994 serializer
995 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
996 .map_err(SerializeError::Backend)?;
997
998 let field_mode = serializer.struct_field_mode();
999 match variant.data.kind {
1000 StructKind::Unit => {}
1001 StructKind::Struct => {
1002 let mut fields: alloc::vec::Vec<_> =
1003 if field_mode == StructFieldMode::Unnamed {
1004 enum_.fields_for_binary_serialize().collect()
1005 } else {
1006 enum_.fields_for_serialize().collect()
1007 };
1008 sort_fields_if_needed(serializer, &mut fields);
1009 for (field_item, field_value) in fields {
1010 serializer
1011 .field_metadata(&field_item)
1012 .map_err(SerializeError::Backend)?;
1013 if field_mode == StructFieldMode::Named {
1014 serializer
1015 .field_key(field_item.effective_name())
1016 .map_err(SerializeError::Backend)?;
1017 }
1018 if let Some(proxy_def) = field_item
1020 .field
1021 .and_then(|f| f.effective_proxy(serializer.format_namespace()))
1022 {
1023 serialize_via_proxy(serializer, field_value, proxy_def)?;
1024 } else {
1025 shared_serialize(serializer, field_value)?;
1026 }
1027 }
1028 }
1029 StructKind::TupleStruct | StructKind::Tuple => {
1030 return Err(SerializeError::Unsupported(Cow::Borrowed(
1031 "internally tagged tuple variants are not supported",
1032 )));
1033 }
1034 }
1035
1036 serializer.end_struct().map_err(SerializeError::Backend)?;
1037 return Ok(());
1038 }
1039 (Some(tag_key), Some(content_key)) => {
1040 let field_mode = serializer.struct_field_mode();
1042 serializer.begin_struct().map_err(SerializeError::Backend)?;
1043 serializer
1044 .field_key(tag_key)
1045 .map_err(SerializeError::Backend)?;
1046 serializer
1047 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1048 .map_err(SerializeError::Backend)?;
1049
1050 match variant.data.kind {
1051 StructKind::Unit => {
1052 }
1054 StructKind::Struct => {
1055 serializer
1056 .field_key(content_key)
1057 .map_err(SerializeError::Backend)?;
1058 serializer.begin_struct().map_err(SerializeError::Backend)?;
1059 let mut fields: alloc::vec::Vec<_> =
1060 if field_mode == StructFieldMode::Unnamed {
1061 enum_.fields_for_binary_serialize().collect()
1062 } else {
1063 enum_.fields_for_serialize().collect()
1064 };
1065 sort_fields_if_needed(serializer, &mut fields);
1066 for (field_item, field_value) in fields {
1067 serializer
1068 .field_metadata(&field_item)
1069 .map_err(SerializeError::Backend)?;
1070 if field_mode == StructFieldMode::Named {
1071 serializer
1072 .field_key(field_item.effective_name())
1073 .map_err(SerializeError::Backend)?;
1074 }
1075 if let Some(proxy_def) = field_item
1077 .field
1078 .and_then(|f| f.effective_proxy(serializer.format_namespace()))
1079 {
1080 serialize_via_proxy(serializer, field_value, proxy_def)?;
1081 } else {
1082 shared_serialize(serializer, field_value)?;
1083 }
1084 }
1085 serializer.end_struct().map_err(SerializeError::Backend)?;
1086 }
1087 StructKind::TupleStruct | StructKind::Tuple => {
1088 serializer
1089 .field_key(content_key)
1090 .map_err(SerializeError::Backend)?;
1091
1092 let field_count = variant.data.fields.len();
1093 if field_count == 1 {
1094 let inner = enum_
1095 .field(0)
1096 .map_err(|_| {
1097 SerializeError::Internal(Cow::Borrowed(
1098 "variant field lookup failed",
1099 ))
1100 })?
1101 .ok_or(SerializeError::Internal(Cow::Borrowed(
1102 "variant reported 1 field but field(0) returned None",
1103 )))?;
1104 shared_serialize(serializer, inner)?;
1105 } else {
1106 serializer.begin_seq().map_err(SerializeError::Backend)?;
1107 for idx in 0..field_count {
1108 let inner = enum_
1109 .field(idx)
1110 .map_err(|_| {
1111 SerializeError::Internal(Cow::Borrowed(
1112 "variant field lookup failed",
1113 ))
1114 })?
1115 .ok_or(SerializeError::Internal(Cow::Borrowed(
1116 "variant field missing while iterating tuple fields",
1117 )))?;
1118 shared_serialize(serializer, inner)?;
1119 }
1120 serializer.end_seq().map_err(SerializeError::Backend)?;
1121 }
1122 }
1123 }
1124
1125 serializer.end_struct().map_err(SerializeError::Backend)?;
1126 return Ok(());
1127 }
1128 (None, Some(_)) => {
1129 return Err(SerializeError::Unsupported(Cow::Borrowed(
1130 "adjacent content key set without tag key",
1131 )));
1132 }
1133 (None, None) => {}
1134 }
1135
1136 trace!(
1140 variant_name = variant.name,
1141 is_other = variant.is_other(),
1142 "serializing enum variant"
1143 );
1144 let field_mode = serializer.struct_field_mode();
1145 let tag_name: Cow<'_, str> = if variant.is_other() {
1146 let mut tag_value: Option<Cow<'_, str>> = None;
1149 let fields_iter: alloc::boxed::Box<
1150 dyn Iterator<Item = (facet_reflect::FieldItem, facet_reflect::Peek<'_, '_>)>,
1151 > = if field_mode == StructFieldMode::Unnamed {
1152 alloc::boxed::Box::new(enum_.fields_for_binary_serialize())
1153 } else {
1154 alloc::boxed::Box::new(enum_.fields_for_serialize())
1155 };
1156 for (field_item, field_value) in fields_iter {
1157 if let Some(field) = field_item.field {
1158 trace!(
1159 field_name = field.name,
1160 is_variant_tag = field.is_variant_tag(),
1161 "checking field for tag"
1162 );
1163 if field.is_variant_tag() {
1164 if let Ok(opt) = field_value.into_option()
1166 && let Some(inner) = opt.value()
1167 && let Some(s) = inner.as_str()
1168 {
1169 tag_value = Some(Cow::Borrowed(s));
1170 }
1171 break;
1172 }
1173 }
1174 }
1175 tag_value.unwrap_or_else(|| Cow::Borrowed(variant.effective_name()))
1176 } else {
1177 Cow::Borrowed(variant.effective_name())
1178 };
1179
1180 let use_tag_syntax = serializer
1182 .write_variant_tag(&tag_name)
1183 .map_err(SerializeError::Backend)?;
1184
1185 if use_tag_syntax {
1186 return match variant.data.kind {
1188 StructKind::Unit => {
1189 Ok(())
1191 }
1192 StructKind::TupleStruct | StructKind::Tuple => {
1193 let field_count = variant.data.fields.len();
1194 if field_count == 1 {
1195 let inner = enum_
1197 .field(0)
1198 .map_err(|_| {
1199 SerializeError::Internal(Cow::Borrowed(
1200 "variant field lookup failed",
1201 ))
1202 })?
1203 .ok_or(SerializeError::Internal(Cow::Borrowed(
1204 "variant reported 1 field but field(0) returned None",
1205 )))?;
1206 shared_serialize(serializer, inner)?;
1207 } else {
1208 serializer
1210 .begin_seq_after_tag()
1211 .map_err(SerializeError::Backend)?;
1212 for idx in 0..field_count {
1213 let inner = enum_
1214 .field(idx)
1215 .map_err(|_| {
1216 SerializeError::Internal(Cow::Borrowed(
1217 "variant field lookup failed",
1218 ))
1219 })?
1220 .ok_or(SerializeError::Internal(Cow::Borrowed(
1221 "variant field missing while iterating tuple fields",
1222 )))?;
1223 shared_serialize(serializer, inner)?;
1224 }
1225 serializer.end_seq().map_err(SerializeError::Backend)?;
1226 }
1227 Ok(())
1228 }
1229 StructKind::Struct => {
1230 let is_other = variant.is_other();
1233 let fields_iter: alloc::boxed::Box<
1234 dyn Iterator<
1235 Item = (facet_reflect::FieldItem, facet_reflect::Peek<'_, '_>),
1236 >,
1237 > = if field_mode == StructFieldMode::Unnamed {
1238 alloc::boxed::Box::new(enum_.fields_for_binary_serialize())
1239 } else {
1240 alloc::boxed::Box::new(enum_.fields_for_serialize())
1241 };
1242 let mut fields: alloc::vec::Vec<_> = fields_iter
1243 .filter(|(field_item, _)| {
1244 if is_other {
1245 field_item
1247 .field
1248 .map(|f| f.metadata_kind().is_none() && !f.is_variant_tag())
1249 .unwrap_or(true)
1250 } else {
1251 true
1252 }
1253 })
1254 .collect();
1255
1256 if fields.is_empty() {
1258 return Ok(());
1259 }
1260
1261 serializer
1262 .begin_struct_after_tag()
1263 .map_err(SerializeError::Backend)?;
1264 sort_fields_if_needed(serializer, &mut fields);
1265 let field_mode = serializer.struct_field_mode();
1266 for (field_item, field_value) in fields {
1267 serializer
1268 .field_metadata(&field_item)
1269 .map_err(SerializeError::Backend)?;
1270 if field_mode == StructFieldMode::Named {
1271 serializer
1272 .field_key(field_item.effective_name())
1273 .map_err(SerializeError::Backend)?;
1274 }
1275 if let Some(proxy_def) = field_item
1276 .field
1277 .and_then(|f| f.effective_proxy(serializer.format_namespace()))
1278 {
1279 serialize_via_proxy(serializer, field_value, proxy_def)?;
1280 } else {
1281 shared_serialize(serializer, field_value)?;
1282 }
1283 }
1284 serializer.end_struct().map_err(SerializeError::Backend)?;
1285 Ok(())
1286 }
1287 };
1288 }
1289
1290 return match variant.data.kind {
1292 StructKind::Unit => {
1293 serializer
1294 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1295 .map_err(SerializeError::Backend)?;
1296 Ok(())
1297 }
1298 StructKind::TupleStruct | StructKind::Tuple => {
1299 serializer.begin_struct().map_err(SerializeError::Backend)?;
1300 serializer
1301 .field_key(variant.effective_name())
1302 .map_err(SerializeError::Backend)?;
1303
1304 let field_count = variant.data.fields.len();
1305 if field_count == 1 {
1306 let inner = enum_
1307 .field(0)
1308 .map_err(|_| {
1309 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1310 })?
1311 .ok_or(SerializeError::Internal(Cow::Borrowed(
1312 "variant reported 1 field but field(0) returned None",
1313 )))?;
1314 if let Some(field_def) = variant.data.fields.first()
1316 && let Some(proxy_def) =
1317 field_def.effective_proxy(serializer.format_namespace())
1318 {
1319 serialize_via_proxy(serializer, inner, proxy_def)?;
1320 } else {
1321 shared_serialize(serializer, inner)?;
1322 }
1323 } else {
1324 serializer.begin_seq().map_err(SerializeError::Backend)?;
1325 for idx in 0..field_count {
1326 let inner = enum_
1327 .field(idx)
1328 .map_err(|_| {
1329 SerializeError::Internal(Cow::Borrowed(
1330 "variant field lookup failed",
1331 ))
1332 })?
1333 .ok_or(SerializeError::Internal(Cow::Borrowed(
1334 "variant field missing while iterating tuple fields",
1335 )))?;
1336 if let Some(field_def) = variant.data.fields.get(idx)
1338 && let Some(proxy_def) =
1339 field_def.effective_proxy(serializer.format_namespace())
1340 {
1341 serialize_via_proxy(serializer, inner, proxy_def)?;
1342 } else {
1343 shared_serialize(serializer, inner)?;
1344 }
1345 }
1346 serializer.end_seq().map_err(SerializeError::Backend)?;
1347 }
1348
1349 serializer.end_struct().map_err(SerializeError::Backend)?;
1350 Ok(())
1351 }
1352 StructKind::Struct => {
1353 let field_mode = serializer.struct_field_mode();
1354 serializer.begin_struct().map_err(SerializeError::Backend)?;
1355 serializer
1356 .field_key(variant.effective_name())
1357 .map_err(SerializeError::Backend)?;
1358
1359 serializer.begin_struct().map_err(SerializeError::Backend)?;
1360 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1361 enum_.fields_for_binary_serialize().collect()
1362 } else {
1363 enum_.fields_for_serialize().collect()
1364 };
1365 sort_fields_if_needed(serializer, &mut fields);
1366 for (field_item, field_value) in fields {
1367 serializer
1368 .field_metadata(&field_item)
1369 .map_err(SerializeError::Backend)?;
1370 if field_mode == StructFieldMode::Named {
1371 serializer
1372 .field_key(field_item.effective_name())
1373 .map_err(SerializeError::Backend)?;
1374 }
1375 if let Some(proxy_def) = field_item
1377 .field
1378 .and_then(|f| f.effective_proxy(serializer.format_namespace()))
1379 {
1380 serialize_via_proxy(serializer, field_value, proxy_def)?;
1381 } else {
1382 shared_serialize(serializer, field_value)?;
1383 }
1384 }
1385 serializer.end_struct().map_err(SerializeError::Backend)?;
1386
1387 serializer.end_struct().map_err(SerializeError::Backend)?;
1388 Ok(())
1389 }
1390 };
1391 }
1392
1393 Err(SerializeError::Unsupported(Cow::Borrowed(
1394 "unsupported value kind for serialization",
1395 )))
1396}
1397
1398fn serialize_dynamic_value<'mem, 'facet, S>(
1399 serializer: &mut S,
1400 dynamic: facet_reflect::PeekDynamicValue<'mem, 'facet>,
1401) -> Result<(), SerializeError<S::Error>>
1402where
1403 S: FormatSerializer,
1404{
1405 let tagged = serializer.dynamic_value_encoding() == DynamicValueEncoding::Tagged;
1406
1407 match dynamic.kind() {
1408 DynValueKind::Null => {
1409 if tagged {
1410 serializer
1411 .dynamic_value_tag(DynamicValueTag::Null)
1412 .map_err(SerializeError::Backend)?;
1413 }
1414 serializer
1415 .scalar(ScalarValue::Null)
1416 .map_err(SerializeError::Backend)
1417 }
1418 DynValueKind::Bool => {
1419 let value = dynamic.as_bool().ok_or_else(|| {
1420 SerializeError::Internal(Cow::Borrowed("dynamic bool missing value"))
1421 })?;
1422 if tagged {
1423 serializer
1424 .dynamic_value_tag(DynamicValueTag::Bool)
1425 .map_err(SerializeError::Backend)?;
1426 }
1427 serializer
1428 .scalar(ScalarValue::Bool(value))
1429 .map_err(SerializeError::Backend)
1430 }
1431 DynValueKind::Number => {
1432 if let Some(n) = dynamic.as_i64() {
1433 if tagged {
1434 serializer
1435 .dynamic_value_tag(DynamicValueTag::I64)
1436 .map_err(SerializeError::Backend)?;
1437 }
1438 serializer
1439 .scalar(ScalarValue::I64(n))
1440 .map_err(SerializeError::Backend)
1441 } else if let Some(n) = dynamic.as_u64() {
1442 if tagged {
1443 serializer
1444 .dynamic_value_tag(DynamicValueTag::U64)
1445 .map_err(SerializeError::Backend)?;
1446 }
1447 serializer
1448 .scalar(ScalarValue::U64(n))
1449 .map_err(SerializeError::Backend)
1450 } else if let Some(n) = dynamic.as_f64() {
1451 if tagged {
1452 serializer
1453 .dynamic_value_tag(DynamicValueTag::F64)
1454 .map_err(SerializeError::Backend)?;
1455 }
1456 serializer
1457 .scalar(ScalarValue::F64(n))
1458 .map_err(SerializeError::Backend)
1459 } else {
1460 Err(SerializeError::Unsupported(Cow::Borrowed(
1461 "dynamic number not representable",
1462 )))
1463 }
1464 }
1465 DynValueKind::String => {
1466 let value = dynamic.as_str().ok_or_else(|| {
1467 SerializeError::Internal(Cow::Borrowed("dynamic string missing value"))
1468 })?;
1469 if tagged {
1470 serializer
1471 .dynamic_value_tag(DynamicValueTag::String)
1472 .map_err(SerializeError::Backend)?;
1473 }
1474 serializer
1475 .scalar(ScalarValue::Str(Cow::Borrowed(value)))
1476 .map_err(SerializeError::Backend)
1477 }
1478 DynValueKind::Bytes => {
1479 let value = dynamic.as_bytes().ok_or_else(|| {
1480 SerializeError::Internal(Cow::Borrowed("dynamic bytes missing value"))
1481 })?;
1482 if tagged {
1483 serializer
1484 .dynamic_value_tag(DynamicValueTag::Bytes)
1485 .map_err(SerializeError::Backend)?;
1486 }
1487 serializer
1488 .scalar(ScalarValue::Bytes(Cow::Borrowed(value)))
1489 .map_err(SerializeError::Backend)
1490 }
1491 DynValueKind::Array => {
1492 let len = dynamic.array_len().ok_or_else(|| {
1493 SerializeError::Internal(Cow::Borrowed("dynamic array missing length"))
1494 })?;
1495 if tagged {
1496 serializer
1497 .dynamic_value_tag(DynamicValueTag::Array)
1498 .map_err(SerializeError::Backend)?;
1499 }
1500 serializer
1501 .begin_seq_with_len(len)
1502 .map_err(SerializeError::Backend)?;
1503 if let Some(iter) = dynamic.array_iter() {
1504 for item in iter {
1505 shared_serialize(serializer, item)?;
1506 }
1507 }
1508 serializer.end_seq().map_err(SerializeError::Backend)
1509 }
1510 DynValueKind::Object => {
1511 let len = dynamic.object_len().ok_or_else(|| {
1512 SerializeError::Internal(Cow::Borrowed("dynamic object missing length"))
1513 })?;
1514 if tagged {
1515 serializer
1516 .dynamic_value_tag(DynamicValueTag::Object)
1517 .map_err(SerializeError::Backend)?;
1518 }
1519 match serializer.map_encoding() {
1520 MapEncoding::Pairs => {
1521 serializer
1522 .begin_map_with_len(len)
1523 .map_err(SerializeError::Backend)?;
1524 if let Some(iter) = dynamic.object_iter() {
1525 for (key, value) in iter {
1526 serializer
1527 .scalar(ScalarValue::Str(Cow::Borrowed(key)))
1528 .map_err(SerializeError::Backend)?;
1529 shared_serialize(serializer, value)?;
1530 }
1531 }
1532 serializer.end_map().map_err(SerializeError::Backend)
1533 }
1534 MapEncoding::Struct => {
1535 serializer.begin_struct().map_err(SerializeError::Backend)?;
1536 if let Some(iter) = dynamic.object_iter() {
1537 for (key, value) in iter {
1538 serializer.field_key(key).map_err(SerializeError::Backend)?;
1539 shared_serialize(serializer, value)?;
1540 }
1541 }
1542 serializer.end_struct().map_err(SerializeError::Backend)
1543 }
1544 }
1545 }
1546 DynValueKind::DateTime => {
1547 let dt = dynamic.as_datetime().ok_or_else(|| {
1548 SerializeError::Internal(Cow::Borrowed("dynamic datetime missing value"))
1549 })?;
1550 if tagged {
1551 serializer
1552 .dynamic_value_tag(DynamicValueTag::DateTime)
1553 .map_err(SerializeError::Backend)?;
1554 }
1555 let s = format_dyn_datetime(dt);
1556 serializer
1557 .scalar(ScalarValue::Str(Cow::Owned(s)))
1558 .map_err(SerializeError::Backend)
1559 }
1560 DynValueKind::QName | DynValueKind::Uuid => Err(SerializeError::Unsupported(
1561 Cow::Borrowed("dynamic QName/Uuid serialization is not supported"),
1562 )),
1563 }
1564}
1565
1566fn format_dyn_datetime(
1567 (year, month, day, hour, minute, second, nanos, kind): (
1568 i32,
1569 u8,
1570 u8,
1571 u8,
1572 u8,
1573 u8,
1574 u32,
1575 DynDateTimeKind,
1576 ),
1577) -> String {
1578 let mut out = String::new();
1579 match kind {
1580 DynDateTimeKind::Offset { offset_minutes } => {
1581 let _ = write!(
1582 out,
1583 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}",
1584 year, month, day, hour, minute, second
1585 );
1586 if nanos > 0 {
1587 let _ = write!(out, ".{:09}", nanos);
1588 }
1589 if offset_minutes == 0 {
1590 out.push('Z');
1591 } else {
1592 let sign = if offset_minutes >= 0 { '+' } else { '-' };
1593 let abs = offset_minutes.unsigned_abs();
1594 let _ = write!(out, "{}{:02}:{:02}", sign, abs / 60, abs % 60);
1595 }
1596 }
1597 DynDateTimeKind::LocalDateTime => {
1598 let _ = write!(
1599 out,
1600 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}",
1601 year, month, day, hour, minute, second
1602 );
1603 if nanos > 0 {
1604 let _ = write!(out, ".{:09}", nanos);
1605 }
1606 }
1607 DynDateTimeKind::LocalDate => {
1608 let _ = write!(out, "{:04}-{:02}-{:02}", year, month, day);
1609 }
1610 DynDateTimeKind::LocalTime => {
1611 let _ = write!(out, "{:02}:{:02}:{:02}", hour, minute, second);
1612 if nanos > 0 {
1613 let _ = write!(out, ".{:09}", nanos);
1614 }
1615 }
1616 }
1617 out
1618}
1619
1620fn serialize_numeric_enum<S>(
1621 serializer: &mut S,
1622 variant: &'static facet_core::Variant,
1623) -> Result<(), SerializeError<S::Error>>
1624where
1625 S: FormatSerializer,
1626{
1627 let discriminant = variant
1628 .discriminant
1629 .ok_or(SerializeError::Unsupported(Cow::Borrowed(
1630 "Enum without a discriminant",
1631 )))?;
1632 serializer
1633 .scalar(ScalarValue::I64(discriminant))
1634 .map_err(SerializeError::Backend)
1635}
1636
1637fn serialize_untagged_enum<'mem, 'facet, S>(
1638 serializer: &mut S,
1639 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1640 variant: &'static facet_core::Variant,
1641) -> Result<(), SerializeError<S::Error>>
1642where
1643 S: FormatSerializer,
1644{
1645 match variant.data.kind {
1646 StructKind::Unit => serializer
1647 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1648 .map_err(SerializeError::Backend),
1649 StructKind::TupleStruct | StructKind::Tuple => {
1650 let field_count = variant.data.fields.len();
1651 if field_count == 1 {
1652 let inner = enum_
1653 .field(0)
1654 .map_err(|_| {
1655 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1656 })?
1657 .ok_or(SerializeError::Internal(Cow::Borrowed(
1658 "variant reported 1 field but field(0) returned None",
1659 )))?;
1660 shared_serialize(serializer, inner)
1661 } else {
1662 serializer.begin_seq().map_err(SerializeError::Backend)?;
1663 for idx in 0..field_count {
1664 let inner = enum_
1665 .field(idx)
1666 .map_err(|_| {
1667 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1668 })?
1669 .ok_or(SerializeError::Internal(Cow::Borrowed(
1670 "variant field missing while iterating tuple fields",
1671 )))?;
1672 shared_serialize(serializer, inner)?;
1673 }
1674 serializer.end_seq().map_err(SerializeError::Backend)?;
1675 Ok(())
1676 }
1677 }
1678 StructKind::Struct => {
1679 let field_mode = serializer.struct_field_mode();
1680 serializer.begin_struct().map_err(SerializeError::Backend)?;
1681 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1682 enum_.fields_for_binary_serialize().collect()
1683 } else {
1684 enum_.fields_for_serialize().collect()
1685 };
1686 sort_fields_if_needed(serializer, &mut fields);
1687 for (field_item, field_value) in fields {
1688 serializer
1689 .field_metadata(&field_item)
1690 .map_err(SerializeError::Backend)?;
1691 if field_mode == StructFieldMode::Named {
1692 serializer
1693 .field_key(field_item.effective_name())
1694 .map_err(SerializeError::Backend)?;
1695 }
1696 if let Some(proxy_def) = field_item
1698 .field
1699 .and_then(|f| f.effective_proxy(serializer.format_namespace()))
1700 {
1701 serialize_via_proxy(serializer, field_value, proxy_def)?;
1702 } else {
1703 shared_serialize(serializer, field_value)?;
1704 }
1705 }
1706 serializer.end_struct().map_err(SerializeError::Backend)?;
1707 Ok(())
1708 }
1709 }
1710}
1711
1712fn deref_if_pointer<'mem, 'facet>(peek: Peek<'mem, 'facet>) -> Peek<'mem, 'facet> {
1714 if let Ok(ptr) = peek.into_pointer()
1715 && let Some(target) = ptr.borrow_inner()
1716 {
1717 return deref_if_pointer(target);
1718 }
1719 peek
1720}
1721
1722#[allow(unsafe_code)]
1730fn serialize_via_proxy<'mem, 'facet, S>(
1731 serializer: &mut S,
1732 value: Peek<'mem, 'facet>,
1733 proxy_def: &'static facet_core::ProxyDef,
1734) -> Result<(), SerializeError<S::Error>>
1735where
1736 S: FormatSerializer,
1737{
1738 use facet_core::PtrUninit;
1739
1740 let proxy_shape = proxy_def.shape;
1741 let proxy_layout = proxy_shape.layout.sized_layout().map_err(|_| {
1742 SerializeError::Unsupported(Cow::Borrowed("proxy type must be sized for serialization"))
1743 })?;
1744
1745 let proxy_mem = unsafe { alloc::alloc::alloc(proxy_layout) };
1747 if proxy_mem.is_null() {
1748 return Err(SerializeError::Internal(Cow::Borrowed(
1749 "failed to allocate proxy memory",
1750 )));
1751 }
1752
1753 let proxy_uninit = PtrUninit::new(proxy_mem);
1755 let convert_result = unsafe { (proxy_def.convert_out)(value.data(), proxy_uninit) };
1756
1757 let proxy_ptr = match convert_result {
1758 Ok(ptr) => ptr,
1759 Err(msg) => {
1760 unsafe { alloc::alloc::dealloc(proxy_mem, proxy_layout) };
1761 return Err(SerializeError::Unsupported(Cow::Owned(msg)));
1762 }
1763 };
1764
1765 let proxy_peek = unsafe { Peek::unchecked_new(proxy_ptr.as_const(), proxy_shape) };
1767 let result = shared_serialize(serializer, proxy_peek);
1768
1769 unsafe {
1771 let _ = proxy_shape.call_drop_in_place(proxy_ptr);
1772 alloc::alloc::dealloc(proxy_mem, proxy_layout);
1773 }
1774
1775 result
1776}
1777
1778pub fn serialize_value_with_shape<S>(
1804 serializer: &mut S,
1805 value: Peek<'_, '_>,
1806 target_shape: &'static Shape,
1807) -> Result<(), SerializeError<S::Error>>
1808where
1809 S: FormatSerializer,
1810{
1811 let dynamic = value.into_dynamic_value().map_err(|_| {
1812 SerializeError::Unsupported(Cow::Borrowed(
1813 "serialize_value_with_shape requires a DynamicValue type",
1814 ))
1815 })?;
1816
1817 serialize_dynamic_with_shape(serializer, dynamic, target_shape, value.shape())
1818}
1819
1820fn serialize_dynamic_with_shape<S>(
1821 serializer: &mut S,
1822 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
1823 target_shape: &'static Shape,
1824 value_shape: &'static Shape,
1825) -> Result<(), SerializeError<S::Error>>
1826where
1827 S: FormatSerializer,
1828{
1829 use facet_core::{ListDef, OptionDef, ScalarType as CoreScalarType, Type, UserType};
1830
1831 if let Def::Pointer(ptr_def) = target_shape.def
1833 && let Some(pointee) = ptr_def.pointee
1834 {
1835 return serialize_dynamic_with_shape(serializer, dynamic, pointee, value_shape);
1836 }
1837
1838 if let Some(inner_shape) = target_shape.inner {
1840 if !matches!(
1842 target_shape.def,
1843 Def::List(_) | Def::Map(_) | Def::Set(_) | Def::Array(_)
1844 ) {
1845 return serialize_dynamic_with_shape(serializer, dynamic, inner_shape, value_shape);
1846 }
1847 }
1848
1849 if let Def::Option(OptionDef { t: inner_shape, .. }) = target_shape.def {
1851 return serialize_option_from_dynamic(serializer, dynamic, inner_shape, value_shape);
1852 }
1853
1854 if let Def::List(ListDef { t: item_shape, .. }) = target_shape.def {
1856 return serialize_list_from_dynamic(serializer, dynamic, item_shape, value_shape);
1857 }
1858
1859 if let Def::Array(array_def) = target_shape.def {
1861 return serialize_array_from_dynamic(serializer, dynamic, array_def.t, value_shape);
1862 }
1863
1864 if let Def::Map(map_def) = target_shape.def {
1866 return serialize_map_from_dynamic(serializer, dynamic, map_def.k, map_def.v, value_shape);
1867 }
1868
1869 if let Some(scalar_type) = CoreScalarType::try_from_shape(target_shape) {
1871 return serialize_scalar_from_dynamic(serializer, dynamic, scalar_type);
1872 }
1873
1874 match target_shape.ty {
1876 Type::User(UserType::Struct(struct_def)) => {
1877 serialize_struct_from_dynamic(serializer, dynamic, struct_def, value_shape)
1878 }
1879 Type::User(UserType::Enum(enum_def)) => {
1880 serialize_enum_from_dynamic(serializer, dynamic, enum_def, target_shape, value_shape)
1881 }
1882 _ => Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
1883 "unsupported target shape for serialize_value_with_shape: {}",
1884 target_shape
1885 )))),
1886 }
1887}
1888
1889fn serialize_option_from_dynamic<S>(
1890 serializer: &mut S,
1891 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
1892 inner_shape: &'static Shape,
1893 value_shape: &'static Shape,
1894) -> Result<(), SerializeError<S::Error>>
1895where
1896 S: FormatSerializer,
1897{
1898 if dynamic.kind() == DynValueKind::Null {
1899 serializer.serialize_none().map_err(SerializeError::Backend)
1900 } else {
1901 serializer
1902 .begin_option_some()
1903 .map_err(SerializeError::Backend)?;
1904 serialize_dynamic_with_shape(serializer, dynamic, inner_shape, value_shape)
1905 }
1906}
1907
1908fn serialize_list_from_dynamic<S>(
1909 serializer: &mut S,
1910 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
1911 item_shape: &'static Shape,
1912 value_shape: &'static Shape,
1913) -> Result<(), SerializeError<S::Error>>
1914where
1915 S: FormatSerializer,
1916{
1917 let len = dynamic.array_len().ok_or_else(|| {
1918 SerializeError::Unsupported(Cow::Borrowed(
1919 "expected array value for list/vec target shape",
1920 ))
1921 })?;
1922
1923 serializer
1924 .begin_seq_with_len(len)
1925 .map_err(SerializeError::Backend)?;
1926
1927 if let Some(iter) = dynamic.array_iter() {
1928 for elem in iter {
1929 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
1930 SerializeError::Internal(Cow::Borrowed("array element is not a dynamic value"))
1931 })?;
1932 serialize_dynamic_with_shape(serializer, elem_dyn, item_shape, value_shape)?;
1933 }
1934 }
1935
1936 serializer.end_seq().map_err(SerializeError::Backend)
1937}
1938
1939fn serialize_array_from_dynamic<S>(
1940 serializer: &mut S,
1941 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
1942 item_shape: &'static Shape,
1943 value_shape: &'static Shape,
1944) -> Result<(), SerializeError<S::Error>>
1945where
1946 S: FormatSerializer,
1947{
1948 serializer.begin_seq().map_err(SerializeError::Backend)?;
1950
1951 if let Some(iter) = dynamic.array_iter() {
1952 for elem in iter {
1953 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
1954 SerializeError::Internal(Cow::Borrowed("array element is not a dynamic value"))
1955 })?;
1956 serialize_dynamic_with_shape(serializer, elem_dyn, item_shape, value_shape)?;
1957 }
1958 }
1959
1960 serializer.end_seq().map_err(SerializeError::Backend)
1961}
1962
1963fn serialize_map_from_dynamic<S>(
1964 serializer: &mut S,
1965 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
1966 key_shape: &'static Shape,
1967 value_shape_inner: &'static Shape,
1968 value_shape: &'static Shape,
1969) -> Result<(), SerializeError<S::Error>>
1970where
1971 S: FormatSerializer,
1972{
1973 let len = dynamic.object_len().ok_or_else(|| {
1974 SerializeError::Unsupported(Cow::Borrowed("expected object value for map target shape"))
1975 })?;
1976
1977 match serializer.map_encoding() {
1978 MapEncoding::Pairs => {
1979 serializer
1980 .begin_map_with_len(len)
1981 .map_err(SerializeError::Backend)?;
1982
1983 if let Some(iter) = dynamic.object_iter() {
1984 for (key, val) in iter {
1985 serialize_string_as_scalar(serializer, key, key_shape)?;
1987 let val_dyn = val.into_dynamic_value().map_err(|_| {
1989 SerializeError::Internal(Cow::Borrowed(
1990 "object value is not a dynamic value",
1991 ))
1992 })?;
1993 serialize_dynamic_with_shape(
1994 serializer,
1995 val_dyn,
1996 value_shape_inner,
1997 value_shape,
1998 )?;
1999 }
2000 }
2001
2002 serializer.end_map().map_err(SerializeError::Backend)
2003 }
2004 MapEncoding::Struct => {
2005 serializer.begin_struct().map_err(SerializeError::Backend)?;
2006
2007 if let Some(iter) = dynamic.object_iter() {
2008 for (key, val) in iter {
2009 serializer.field_key(key).map_err(SerializeError::Backend)?;
2010 let val_dyn = val.into_dynamic_value().map_err(|_| {
2011 SerializeError::Internal(Cow::Borrowed(
2012 "object value is not a dynamic value",
2013 ))
2014 })?;
2015 serialize_dynamic_with_shape(
2016 serializer,
2017 val_dyn,
2018 value_shape_inner,
2019 value_shape,
2020 )?;
2021 }
2022 }
2023
2024 serializer.end_struct().map_err(SerializeError::Backend)
2025 }
2026 }
2027}
2028
2029fn serialize_string_as_scalar<S>(
2030 serializer: &mut S,
2031 s: &str,
2032 _key_shape: &'static Shape,
2033) -> Result<(), SerializeError<S::Error>>
2034where
2035 S: FormatSerializer,
2036{
2037 serializer
2040 .scalar(ScalarValue::Str(Cow::Borrowed(s)))
2041 .map_err(SerializeError::Backend)
2042}
2043
2044fn serialize_scalar_from_dynamic<S>(
2045 serializer: &mut S,
2046 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2047 scalar_type: facet_core::ScalarType,
2048) -> Result<(), SerializeError<S::Error>>
2049where
2050 S: FormatSerializer,
2051{
2052 use facet_core::ScalarType as ST;
2053
2054 match scalar_type {
2055 ST::Unit => serializer
2056 .scalar(ScalarValue::Null)
2057 .map_err(SerializeError::Backend),
2058 ST::Bool => {
2059 let v = dynamic
2060 .as_bool()
2061 .ok_or_else(|| SerializeError::Unsupported(Cow::Borrowed("expected bool value")))?;
2062 serializer
2063 .scalar(ScalarValue::Bool(v))
2064 .map_err(SerializeError::Backend)
2065 }
2066 ST::Char => {
2067 let s = dynamic.as_str().ok_or_else(|| {
2068 SerializeError::Unsupported(Cow::Borrowed("expected string value for char"))
2069 })?;
2070 let c = s.chars().next().ok_or_else(|| {
2071 SerializeError::Unsupported(Cow::Borrowed("expected non-empty string for char"))
2072 })?;
2073 serializer
2074 .scalar(ScalarValue::Char(c))
2075 .map_err(SerializeError::Backend)
2076 }
2077 ST::Str | ST::String | ST::CowStr => {
2078 let s = dynamic.as_str().ok_or_else(|| {
2079 SerializeError::Unsupported(Cow::Borrowed("expected string value"))
2080 })?;
2081 serializer
2082 .scalar(ScalarValue::Str(Cow::Borrowed(s)))
2083 .map_err(SerializeError::Backend)
2084 }
2085 ST::U8 | ST::U16 | ST::U32 | ST::U64 | ST::USize => {
2086 let n = dynamic.as_u64().ok_or_else(|| {
2087 SerializeError::Unsupported(Cow::Borrowed("expected unsigned integer value"))
2088 })?;
2089 serializer
2090 .scalar(ScalarValue::U64(n))
2091 .map_err(SerializeError::Backend)
2092 }
2093 ST::U128 => {
2094 let n = dynamic.as_u64().ok_or_else(|| {
2095 SerializeError::Unsupported(Cow::Borrowed("expected unsigned integer value"))
2096 })?;
2097 serializer
2098 .scalar(ScalarValue::U128(n as u128))
2099 .map_err(SerializeError::Backend)
2100 }
2101 ST::I8 | ST::I16 | ST::I32 | ST::I64 | ST::ISize => {
2102 let n = dynamic.as_i64().ok_or_else(|| {
2103 SerializeError::Unsupported(Cow::Borrowed("expected signed integer value"))
2104 })?;
2105 serializer
2106 .scalar(ScalarValue::I64(n))
2107 .map_err(SerializeError::Backend)
2108 }
2109 ST::I128 => {
2110 let n = dynamic.as_i64().ok_or_else(|| {
2111 SerializeError::Unsupported(Cow::Borrowed("expected signed integer value"))
2112 })?;
2113 serializer
2114 .scalar(ScalarValue::I128(n as i128))
2115 .map_err(SerializeError::Backend)
2116 }
2117 ST::F32 | ST::F64 => {
2118 let n = dynamic.as_f64().ok_or_else(|| {
2119 SerializeError::Unsupported(Cow::Borrowed("expected float value"))
2120 })?;
2121 serializer
2122 .scalar(ScalarValue::F64(n))
2123 .map_err(SerializeError::Backend)
2124 }
2125 _ => Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2126 "unsupported scalar type: {:?}",
2127 scalar_type
2128 )))),
2129 }
2130}
2131
2132fn serialize_struct_from_dynamic<S>(
2133 serializer: &mut S,
2134 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2135 struct_def: facet_core::StructType,
2136 value_shape: &'static Shape,
2137) -> Result<(), SerializeError<S::Error>>
2138where
2139 S: FormatSerializer,
2140{
2141 let is_tuple = matches!(struct_def.kind, StructKind::Tuple | StructKind::TupleStruct);
2142
2143 if is_tuple {
2144 serializer.begin_seq().map_err(SerializeError::Backend)?;
2146
2147 let iter = dynamic.array_iter().ok_or_else(|| {
2148 SerializeError::Unsupported(Cow::Borrowed("expected array value for tuple"))
2149 })?;
2150
2151 for (field, elem) in struct_def.fields.iter().zip(iter) {
2152 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2153 SerializeError::Internal(Cow::Borrowed("tuple element is not a dynamic value"))
2154 })?;
2155 serialize_dynamic_with_shape(serializer, elem_dyn, field.shape(), value_shape)?;
2156 }
2157
2158 serializer.end_seq().map_err(SerializeError::Backend)
2159 } else {
2160 let field_mode = serializer.struct_field_mode();
2162
2163 serializer.begin_struct().map_err(SerializeError::Backend)?;
2164
2165 for field in struct_def.fields {
2166 if field.is_metadata() {
2168 continue;
2169 }
2170
2171 let field_name = field.name;
2172 let field_value = dynamic.object_get(field_name).ok_or_else(|| {
2173 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2174 "missing field '{}' in object",
2175 field_name
2176 )))
2177 })?;
2178
2179 if field_mode == StructFieldMode::Named {
2180 serializer
2181 .field_key(field_name)
2182 .map_err(SerializeError::Backend)?;
2183 }
2184
2185 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
2186 SerializeError::Internal(Cow::Borrowed("field value is not a dynamic value"))
2187 })?;
2188 serialize_dynamic_with_shape(serializer, field_dyn, field.shape(), value_shape)?;
2189 }
2190
2191 serializer.end_struct().map_err(SerializeError::Backend)
2192 }
2193}
2194
2195fn serialize_enum_from_dynamic<S>(
2196 serializer: &mut S,
2197 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2198 enum_def: facet_core::EnumType,
2199 target_shape: &'static Shape,
2200 value_shape: &'static Shape,
2201) -> Result<(), SerializeError<S::Error>>
2202where
2203 S: FormatSerializer,
2204{
2205 let use_index = serializer.enum_variant_encoding() == EnumVariantEncoding::Index;
2211
2212 match dynamic.kind() {
2213 DynValueKind::String => {
2215 let variant_name = dynamic.as_str().ok_or_else(|| {
2216 SerializeError::Internal(Cow::Borrowed("expected string for unit variant"))
2217 })?;
2218
2219 let (variant_index, variant) = enum_def
2220 .variants
2221 .iter()
2222 .enumerate()
2223 .find(|(_, v)| v.effective_name() == variant_name)
2224 .ok_or_else(|| {
2225 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2226 "unknown variant '{}'",
2227 variant_name
2228 )))
2229 })?;
2230
2231 if use_index {
2232 serializer
2233 .begin_enum_variant(variant_index, variant.effective_name())
2234 .map_err(SerializeError::Backend)?;
2235 Ok(())
2237 } else {
2238 serializer
2239 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
2240 .map_err(SerializeError::Backend)
2241 }
2242 }
2243
2244 DynValueKind::Object => {
2246 let obj_len = dynamic.object_len().unwrap_or(0);
2248 if obj_len != 1 {
2249 return Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2250 "expected single-key object for enum variant, got {} keys",
2251 obj_len
2252 ))));
2253 }
2254
2255 let (variant_name, payload) = dynamic.object_get_entry(0).ok_or_else(|| {
2256 SerializeError::Internal(Cow::Borrowed("expected object entry for enum variant"))
2257 })?;
2258
2259 let (variant_index, variant) = enum_def
2260 .variants
2261 .iter()
2262 .enumerate()
2263 .find(|(_, v)| v.effective_name() == variant_name)
2264 .ok_or_else(|| {
2265 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2266 "unknown variant '{}'",
2267 variant_name
2268 )))
2269 })?;
2270
2271 let payload_dyn = payload.into_dynamic_value().map_err(|_| {
2272 SerializeError::Internal(Cow::Borrowed("variant payload is not a dynamic value"))
2273 })?;
2274
2275 if use_index {
2276 serializer
2277 .begin_enum_variant(variant_index, variant.effective_name())
2278 .map_err(SerializeError::Backend)?;
2279
2280 match variant.data.kind {
2282 StructKind::Unit => {
2283 }
2285 StructKind::TupleStruct | StructKind::Tuple => {
2286 if variant.data.fields.len() == 1 {
2287 serialize_dynamic_with_shape(
2289 serializer,
2290 payload_dyn,
2291 variant.data.fields[0].shape(),
2292 value_shape,
2293 )?;
2294 } else {
2295 let iter = payload_dyn.array_iter().ok_or_else(|| {
2297 SerializeError::Unsupported(Cow::Borrowed(
2298 "expected array for tuple variant payload",
2299 ))
2300 })?;
2301
2302 for (field, elem) in variant.data.fields.iter().zip(iter) {
2303 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2304 SerializeError::Internal(Cow::Borrowed(
2305 "tuple element is not a dynamic value",
2306 ))
2307 })?;
2308 serialize_dynamic_with_shape(
2309 serializer,
2310 elem_dyn,
2311 field.shape(),
2312 value_shape,
2313 )?;
2314 }
2315 }
2316 }
2317 StructKind::Struct => {
2318 for field in variant.data.fields {
2320 let field_value =
2321 payload_dyn.object_get(field.name).ok_or_else(|| {
2322 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2323 "missing field '{}' in struct variant",
2324 field.name
2325 )))
2326 })?;
2327 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
2328 SerializeError::Internal(Cow::Borrowed(
2329 "field value is not a dynamic value",
2330 ))
2331 })?;
2332 serialize_dynamic_with_shape(
2333 serializer,
2334 field_dyn,
2335 field.shape(),
2336 value_shape,
2337 )?;
2338 }
2339 }
2340 }
2341
2342 Ok(())
2343 } else {
2344 serializer.begin_struct().map_err(SerializeError::Backend)?;
2346 serializer
2347 .field_key(variant.effective_name())
2348 .map_err(SerializeError::Backend)?;
2349
2350 match variant.data.kind {
2351 StructKind::Unit => {
2352 serializer
2353 .scalar(ScalarValue::Null)
2354 .map_err(SerializeError::Backend)?;
2355 }
2356 StructKind::TupleStruct | StructKind::Tuple => {
2357 if variant.data.fields.len() == 1 {
2358 serialize_dynamic_with_shape(
2359 serializer,
2360 payload_dyn,
2361 variant.data.fields[0].shape(),
2362 value_shape,
2363 )?;
2364 } else {
2365 serializer.begin_seq().map_err(SerializeError::Backend)?;
2366 let iter = payload_dyn.array_iter().ok_or_else(|| {
2367 SerializeError::Unsupported(Cow::Borrowed(
2368 "expected array for tuple variant",
2369 ))
2370 })?;
2371 for (field, elem) in variant.data.fields.iter().zip(iter) {
2372 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2373 SerializeError::Internal(Cow::Borrowed(
2374 "element is not a dynamic value",
2375 ))
2376 })?;
2377 serialize_dynamic_with_shape(
2378 serializer,
2379 elem_dyn,
2380 field.shape(),
2381 value_shape,
2382 )?;
2383 }
2384 serializer.end_seq().map_err(SerializeError::Backend)?;
2385 }
2386 }
2387 StructKind::Struct => {
2388 serializer.begin_struct().map_err(SerializeError::Backend)?;
2389 for field in variant.data.fields {
2390 let field_value =
2391 payload_dyn.object_get(field.name).ok_or_else(|| {
2392 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2393 "missing field '{}'",
2394 field.name
2395 )))
2396 })?;
2397 serializer
2398 .field_key(field.name)
2399 .map_err(SerializeError::Backend)?;
2400 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
2401 SerializeError::Internal(Cow::Borrowed(
2402 "field is not a dynamic value",
2403 ))
2404 })?;
2405 serialize_dynamic_with_shape(
2406 serializer,
2407 field_dyn,
2408 field.shape(),
2409 value_shape,
2410 )?;
2411 }
2412 serializer.end_struct().map_err(SerializeError::Backend)?;
2413 }
2414 }
2415
2416 serializer.end_struct().map_err(SerializeError::Backend)
2417 }
2418 }
2419
2420 DynValueKind::Null => {
2422 if let Some((variant_index, variant)) = enum_def
2425 .variants
2426 .iter()
2427 .enumerate()
2428 .find(|(_, v)| v.name.eq_ignore_ascii_case("null") || v.name == "None")
2429 {
2430 if use_index {
2431 serializer
2432 .begin_enum_variant(variant_index, variant.effective_name())
2433 .map_err(SerializeError::Backend)?;
2434 Ok(())
2435 } else {
2436 serializer
2437 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
2438 .map_err(SerializeError::Backend)
2439 }
2440 } else {
2441 Err(SerializeError::Unsupported(Cow::Borrowed(
2442 "null value for enum without null/None variant",
2443 )))
2444 }
2445 }
2446
2447 _ => {
2448 let _ = target_shape; Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2452 "unsupported dynamic value kind {:?} for enum serialization",
2453 dynamic.kind()
2454 ))))
2455 }
2456 }
2457}