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 shared_serialize(serializer, inner)?;
1315 } else {
1316 serializer.begin_seq().map_err(SerializeError::Backend)?;
1317 for idx in 0..field_count {
1318 let inner = enum_
1319 .field(idx)
1320 .map_err(|_| {
1321 SerializeError::Internal(Cow::Borrowed(
1322 "variant field lookup failed",
1323 ))
1324 })?
1325 .ok_or(SerializeError::Internal(Cow::Borrowed(
1326 "variant field missing while iterating tuple fields",
1327 )))?;
1328 shared_serialize(serializer, inner)?;
1329 }
1330 serializer.end_seq().map_err(SerializeError::Backend)?;
1331 }
1332
1333 serializer.end_struct().map_err(SerializeError::Backend)?;
1334 Ok(())
1335 }
1336 StructKind::Struct => {
1337 let field_mode = serializer.struct_field_mode();
1338 serializer.begin_struct().map_err(SerializeError::Backend)?;
1339 serializer
1340 .field_key(variant.effective_name())
1341 .map_err(SerializeError::Backend)?;
1342
1343 serializer.begin_struct().map_err(SerializeError::Backend)?;
1344 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1345 enum_.fields_for_binary_serialize().collect()
1346 } else {
1347 enum_.fields_for_serialize().collect()
1348 };
1349 sort_fields_if_needed(serializer, &mut fields);
1350 for (field_item, field_value) in fields {
1351 serializer
1352 .field_metadata(&field_item)
1353 .map_err(SerializeError::Backend)?;
1354 if field_mode == StructFieldMode::Named {
1355 serializer
1356 .field_key(field_item.effective_name())
1357 .map_err(SerializeError::Backend)?;
1358 }
1359 if let Some(proxy_def) = field_item
1361 .field
1362 .and_then(|f| f.effective_proxy(serializer.format_namespace()))
1363 {
1364 serialize_via_proxy(serializer, field_value, proxy_def)?;
1365 } else {
1366 shared_serialize(serializer, field_value)?;
1367 }
1368 }
1369 serializer.end_struct().map_err(SerializeError::Backend)?;
1370
1371 serializer.end_struct().map_err(SerializeError::Backend)?;
1372 Ok(())
1373 }
1374 };
1375 }
1376
1377 Err(SerializeError::Unsupported(Cow::Borrowed(
1378 "unsupported value kind for serialization",
1379 )))
1380}
1381
1382fn serialize_dynamic_value<'mem, 'facet, S>(
1383 serializer: &mut S,
1384 dynamic: facet_reflect::PeekDynamicValue<'mem, 'facet>,
1385) -> Result<(), SerializeError<S::Error>>
1386where
1387 S: FormatSerializer,
1388{
1389 let tagged = serializer.dynamic_value_encoding() == DynamicValueEncoding::Tagged;
1390
1391 match dynamic.kind() {
1392 DynValueKind::Null => {
1393 if tagged {
1394 serializer
1395 .dynamic_value_tag(DynamicValueTag::Null)
1396 .map_err(SerializeError::Backend)?;
1397 }
1398 serializer
1399 .scalar(ScalarValue::Null)
1400 .map_err(SerializeError::Backend)
1401 }
1402 DynValueKind::Bool => {
1403 let value = dynamic.as_bool().ok_or_else(|| {
1404 SerializeError::Internal(Cow::Borrowed("dynamic bool missing value"))
1405 })?;
1406 if tagged {
1407 serializer
1408 .dynamic_value_tag(DynamicValueTag::Bool)
1409 .map_err(SerializeError::Backend)?;
1410 }
1411 serializer
1412 .scalar(ScalarValue::Bool(value))
1413 .map_err(SerializeError::Backend)
1414 }
1415 DynValueKind::Number => {
1416 if let Some(n) = dynamic.as_i64() {
1417 if tagged {
1418 serializer
1419 .dynamic_value_tag(DynamicValueTag::I64)
1420 .map_err(SerializeError::Backend)?;
1421 }
1422 serializer
1423 .scalar(ScalarValue::I64(n))
1424 .map_err(SerializeError::Backend)
1425 } else if let Some(n) = dynamic.as_u64() {
1426 if tagged {
1427 serializer
1428 .dynamic_value_tag(DynamicValueTag::U64)
1429 .map_err(SerializeError::Backend)?;
1430 }
1431 serializer
1432 .scalar(ScalarValue::U64(n))
1433 .map_err(SerializeError::Backend)
1434 } else if let Some(n) = dynamic.as_f64() {
1435 if tagged {
1436 serializer
1437 .dynamic_value_tag(DynamicValueTag::F64)
1438 .map_err(SerializeError::Backend)?;
1439 }
1440 serializer
1441 .scalar(ScalarValue::F64(n))
1442 .map_err(SerializeError::Backend)
1443 } else {
1444 Err(SerializeError::Unsupported(Cow::Borrowed(
1445 "dynamic number not representable",
1446 )))
1447 }
1448 }
1449 DynValueKind::String => {
1450 let value = dynamic.as_str().ok_or_else(|| {
1451 SerializeError::Internal(Cow::Borrowed("dynamic string missing value"))
1452 })?;
1453 if tagged {
1454 serializer
1455 .dynamic_value_tag(DynamicValueTag::String)
1456 .map_err(SerializeError::Backend)?;
1457 }
1458 serializer
1459 .scalar(ScalarValue::Str(Cow::Borrowed(value)))
1460 .map_err(SerializeError::Backend)
1461 }
1462 DynValueKind::Bytes => {
1463 let value = dynamic.as_bytes().ok_or_else(|| {
1464 SerializeError::Internal(Cow::Borrowed("dynamic bytes missing value"))
1465 })?;
1466 if tagged {
1467 serializer
1468 .dynamic_value_tag(DynamicValueTag::Bytes)
1469 .map_err(SerializeError::Backend)?;
1470 }
1471 serializer
1472 .scalar(ScalarValue::Bytes(Cow::Borrowed(value)))
1473 .map_err(SerializeError::Backend)
1474 }
1475 DynValueKind::Array => {
1476 let len = dynamic.array_len().ok_or_else(|| {
1477 SerializeError::Internal(Cow::Borrowed("dynamic array missing length"))
1478 })?;
1479 if tagged {
1480 serializer
1481 .dynamic_value_tag(DynamicValueTag::Array)
1482 .map_err(SerializeError::Backend)?;
1483 }
1484 serializer
1485 .begin_seq_with_len(len)
1486 .map_err(SerializeError::Backend)?;
1487 if let Some(iter) = dynamic.array_iter() {
1488 for item in iter {
1489 shared_serialize(serializer, item)?;
1490 }
1491 }
1492 serializer.end_seq().map_err(SerializeError::Backend)
1493 }
1494 DynValueKind::Object => {
1495 let len = dynamic.object_len().ok_or_else(|| {
1496 SerializeError::Internal(Cow::Borrowed("dynamic object missing length"))
1497 })?;
1498 if tagged {
1499 serializer
1500 .dynamic_value_tag(DynamicValueTag::Object)
1501 .map_err(SerializeError::Backend)?;
1502 }
1503 match serializer.map_encoding() {
1504 MapEncoding::Pairs => {
1505 serializer
1506 .begin_map_with_len(len)
1507 .map_err(SerializeError::Backend)?;
1508 if let Some(iter) = dynamic.object_iter() {
1509 for (key, value) in iter {
1510 serializer
1511 .scalar(ScalarValue::Str(Cow::Borrowed(key)))
1512 .map_err(SerializeError::Backend)?;
1513 shared_serialize(serializer, value)?;
1514 }
1515 }
1516 serializer.end_map().map_err(SerializeError::Backend)
1517 }
1518 MapEncoding::Struct => {
1519 serializer.begin_struct().map_err(SerializeError::Backend)?;
1520 if let Some(iter) = dynamic.object_iter() {
1521 for (key, value) in iter {
1522 serializer.field_key(key).map_err(SerializeError::Backend)?;
1523 shared_serialize(serializer, value)?;
1524 }
1525 }
1526 serializer.end_struct().map_err(SerializeError::Backend)
1527 }
1528 }
1529 }
1530 DynValueKind::DateTime => {
1531 let dt = dynamic.as_datetime().ok_or_else(|| {
1532 SerializeError::Internal(Cow::Borrowed("dynamic datetime missing value"))
1533 })?;
1534 if tagged {
1535 serializer
1536 .dynamic_value_tag(DynamicValueTag::DateTime)
1537 .map_err(SerializeError::Backend)?;
1538 }
1539 let s = format_dyn_datetime(dt);
1540 serializer
1541 .scalar(ScalarValue::Str(Cow::Owned(s)))
1542 .map_err(SerializeError::Backend)
1543 }
1544 DynValueKind::QName | DynValueKind::Uuid => Err(SerializeError::Unsupported(
1545 Cow::Borrowed("dynamic QName/Uuid serialization is not supported"),
1546 )),
1547 }
1548}
1549
1550fn format_dyn_datetime(
1551 (year, month, day, hour, minute, second, nanos, kind): (
1552 i32,
1553 u8,
1554 u8,
1555 u8,
1556 u8,
1557 u8,
1558 u32,
1559 DynDateTimeKind,
1560 ),
1561) -> String {
1562 let mut out = String::new();
1563 match kind {
1564 DynDateTimeKind::Offset { offset_minutes } => {
1565 let _ = write!(
1566 out,
1567 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}",
1568 year, month, day, hour, minute, second
1569 );
1570 if nanos > 0 {
1571 let _ = write!(out, ".{:09}", nanos);
1572 }
1573 if offset_minutes == 0 {
1574 out.push('Z');
1575 } else {
1576 let sign = if offset_minutes >= 0 { '+' } else { '-' };
1577 let abs = offset_minutes.unsigned_abs();
1578 let _ = write!(out, "{}{:02}:{:02}", sign, abs / 60, abs % 60);
1579 }
1580 }
1581 DynDateTimeKind::LocalDateTime => {
1582 let _ = write!(
1583 out,
1584 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}",
1585 year, month, day, hour, minute, second
1586 );
1587 if nanos > 0 {
1588 let _ = write!(out, ".{:09}", nanos);
1589 }
1590 }
1591 DynDateTimeKind::LocalDate => {
1592 let _ = write!(out, "{:04}-{:02}-{:02}", year, month, day);
1593 }
1594 DynDateTimeKind::LocalTime => {
1595 let _ = write!(out, "{:02}:{:02}:{:02}", hour, minute, second);
1596 if nanos > 0 {
1597 let _ = write!(out, ".{:09}", nanos);
1598 }
1599 }
1600 }
1601 out
1602}
1603
1604fn serialize_numeric_enum<S>(
1605 serializer: &mut S,
1606 variant: &'static facet_core::Variant,
1607) -> Result<(), SerializeError<S::Error>>
1608where
1609 S: FormatSerializer,
1610{
1611 let discriminant = variant
1612 .discriminant
1613 .ok_or(SerializeError::Unsupported(Cow::Borrowed(
1614 "Enum without a discriminant",
1615 )))?;
1616 serializer
1617 .scalar(ScalarValue::I64(discriminant))
1618 .map_err(SerializeError::Backend)
1619}
1620
1621fn serialize_untagged_enum<'mem, 'facet, S>(
1622 serializer: &mut S,
1623 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1624 variant: &'static facet_core::Variant,
1625) -> Result<(), SerializeError<S::Error>>
1626where
1627 S: FormatSerializer,
1628{
1629 match variant.data.kind {
1630 StructKind::Unit => serializer
1631 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1632 .map_err(SerializeError::Backend),
1633 StructKind::TupleStruct | StructKind::Tuple => {
1634 let field_count = variant.data.fields.len();
1635 if field_count == 1 {
1636 let inner = enum_
1637 .field(0)
1638 .map_err(|_| {
1639 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1640 })?
1641 .ok_or(SerializeError::Internal(Cow::Borrowed(
1642 "variant reported 1 field but field(0) returned None",
1643 )))?;
1644 shared_serialize(serializer, inner)
1645 } else {
1646 serializer.begin_seq().map_err(SerializeError::Backend)?;
1647 for idx in 0..field_count {
1648 let inner = enum_
1649 .field(idx)
1650 .map_err(|_| {
1651 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1652 })?
1653 .ok_or(SerializeError::Internal(Cow::Borrowed(
1654 "variant field missing while iterating tuple fields",
1655 )))?;
1656 shared_serialize(serializer, inner)?;
1657 }
1658 serializer.end_seq().map_err(SerializeError::Backend)?;
1659 Ok(())
1660 }
1661 }
1662 StructKind::Struct => {
1663 let field_mode = serializer.struct_field_mode();
1664 serializer.begin_struct().map_err(SerializeError::Backend)?;
1665 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1666 enum_.fields_for_binary_serialize().collect()
1667 } else {
1668 enum_.fields_for_serialize().collect()
1669 };
1670 sort_fields_if_needed(serializer, &mut fields);
1671 for (field_item, field_value) in fields {
1672 serializer
1673 .field_metadata(&field_item)
1674 .map_err(SerializeError::Backend)?;
1675 if field_mode == StructFieldMode::Named {
1676 serializer
1677 .field_key(field_item.effective_name())
1678 .map_err(SerializeError::Backend)?;
1679 }
1680 if let Some(proxy_def) = field_item
1682 .field
1683 .and_then(|f| f.effective_proxy(serializer.format_namespace()))
1684 {
1685 serialize_via_proxy(serializer, field_value, proxy_def)?;
1686 } else {
1687 shared_serialize(serializer, field_value)?;
1688 }
1689 }
1690 serializer.end_struct().map_err(SerializeError::Backend)?;
1691 Ok(())
1692 }
1693 }
1694}
1695
1696fn deref_if_pointer<'mem, 'facet>(peek: Peek<'mem, 'facet>) -> Peek<'mem, 'facet> {
1698 if let Ok(ptr) = peek.into_pointer()
1699 && let Some(target) = ptr.borrow_inner()
1700 {
1701 return deref_if_pointer(target);
1702 }
1703 peek
1704}
1705
1706#[allow(unsafe_code)]
1714fn serialize_via_proxy<'mem, 'facet, S>(
1715 serializer: &mut S,
1716 value: Peek<'mem, 'facet>,
1717 proxy_def: &'static facet_core::ProxyDef,
1718) -> Result<(), SerializeError<S::Error>>
1719where
1720 S: FormatSerializer,
1721{
1722 use facet_core::PtrUninit;
1723
1724 let proxy_shape = proxy_def.shape;
1725 let proxy_layout = proxy_shape.layout.sized_layout().map_err(|_| {
1726 SerializeError::Unsupported(Cow::Borrowed("proxy type must be sized for serialization"))
1727 })?;
1728
1729 let proxy_mem = unsafe { alloc::alloc::alloc(proxy_layout) };
1731 if proxy_mem.is_null() {
1732 return Err(SerializeError::Internal(Cow::Borrowed(
1733 "failed to allocate proxy memory",
1734 )));
1735 }
1736
1737 let proxy_uninit = PtrUninit::new(proxy_mem);
1739 let convert_result = unsafe { (proxy_def.convert_out)(value.data(), proxy_uninit) };
1740
1741 let proxy_ptr = match convert_result {
1742 Ok(ptr) => ptr,
1743 Err(msg) => {
1744 unsafe { alloc::alloc::dealloc(proxy_mem, proxy_layout) };
1745 return Err(SerializeError::Unsupported(Cow::Owned(msg)));
1746 }
1747 };
1748
1749 let proxy_peek = unsafe { Peek::unchecked_new(proxy_ptr.as_const(), proxy_shape) };
1751 let result = shared_serialize(serializer, proxy_peek);
1752
1753 unsafe {
1755 let _ = proxy_shape.call_drop_in_place(proxy_ptr);
1756 alloc::alloc::dealloc(proxy_mem, proxy_layout);
1757 }
1758
1759 result
1760}
1761
1762pub fn serialize_value_with_shape<S>(
1788 serializer: &mut S,
1789 value: Peek<'_, '_>,
1790 target_shape: &'static Shape,
1791) -> Result<(), SerializeError<S::Error>>
1792where
1793 S: FormatSerializer,
1794{
1795 let dynamic = value.into_dynamic_value().map_err(|_| {
1796 SerializeError::Unsupported(Cow::Borrowed(
1797 "serialize_value_with_shape requires a DynamicValue type",
1798 ))
1799 })?;
1800
1801 serialize_dynamic_with_shape(serializer, dynamic, target_shape, value.shape())
1802}
1803
1804fn serialize_dynamic_with_shape<S>(
1805 serializer: &mut S,
1806 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
1807 target_shape: &'static Shape,
1808 value_shape: &'static Shape,
1809) -> Result<(), SerializeError<S::Error>>
1810where
1811 S: FormatSerializer,
1812{
1813 use facet_core::{ListDef, OptionDef, ScalarType as CoreScalarType, Type, UserType};
1814
1815 if let Def::Pointer(ptr_def) = target_shape.def
1817 && let Some(pointee) = ptr_def.pointee
1818 {
1819 return serialize_dynamic_with_shape(serializer, dynamic, pointee, value_shape);
1820 }
1821
1822 if let Some(inner_shape) = target_shape.inner {
1824 if !matches!(
1826 target_shape.def,
1827 Def::List(_) | Def::Map(_) | Def::Set(_) | Def::Array(_)
1828 ) {
1829 return serialize_dynamic_with_shape(serializer, dynamic, inner_shape, value_shape);
1830 }
1831 }
1832
1833 if let Def::Option(OptionDef { t: inner_shape, .. }) = target_shape.def {
1835 return serialize_option_from_dynamic(serializer, dynamic, inner_shape, value_shape);
1836 }
1837
1838 if let Def::List(ListDef { t: item_shape, .. }) = target_shape.def {
1840 return serialize_list_from_dynamic(serializer, dynamic, item_shape, value_shape);
1841 }
1842
1843 if let Def::Array(array_def) = target_shape.def {
1845 return serialize_array_from_dynamic(serializer, dynamic, array_def.t, value_shape);
1846 }
1847
1848 if let Def::Map(map_def) = target_shape.def {
1850 return serialize_map_from_dynamic(serializer, dynamic, map_def.k, map_def.v, value_shape);
1851 }
1852
1853 if let Some(scalar_type) = CoreScalarType::try_from_shape(target_shape) {
1855 return serialize_scalar_from_dynamic(serializer, dynamic, scalar_type);
1856 }
1857
1858 match target_shape.ty {
1860 Type::User(UserType::Struct(struct_def)) => {
1861 serialize_struct_from_dynamic(serializer, dynamic, struct_def, value_shape)
1862 }
1863 Type::User(UserType::Enum(enum_def)) => {
1864 serialize_enum_from_dynamic(serializer, dynamic, enum_def, target_shape, value_shape)
1865 }
1866 _ => Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
1867 "unsupported target shape for serialize_value_with_shape: {}",
1868 target_shape
1869 )))),
1870 }
1871}
1872
1873fn serialize_option_from_dynamic<S>(
1874 serializer: &mut S,
1875 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
1876 inner_shape: &'static Shape,
1877 value_shape: &'static Shape,
1878) -> Result<(), SerializeError<S::Error>>
1879where
1880 S: FormatSerializer,
1881{
1882 if dynamic.kind() == DynValueKind::Null {
1883 serializer.serialize_none().map_err(SerializeError::Backend)
1884 } else {
1885 serializer
1886 .begin_option_some()
1887 .map_err(SerializeError::Backend)?;
1888 serialize_dynamic_with_shape(serializer, dynamic, inner_shape, value_shape)
1889 }
1890}
1891
1892fn serialize_list_from_dynamic<S>(
1893 serializer: &mut S,
1894 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
1895 item_shape: &'static Shape,
1896 value_shape: &'static Shape,
1897) -> Result<(), SerializeError<S::Error>>
1898where
1899 S: FormatSerializer,
1900{
1901 let len = dynamic.array_len().ok_or_else(|| {
1902 SerializeError::Unsupported(Cow::Borrowed(
1903 "expected array value for list/vec target shape",
1904 ))
1905 })?;
1906
1907 serializer
1908 .begin_seq_with_len(len)
1909 .map_err(SerializeError::Backend)?;
1910
1911 if let Some(iter) = dynamic.array_iter() {
1912 for elem in iter {
1913 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
1914 SerializeError::Internal(Cow::Borrowed("array element is not a dynamic value"))
1915 })?;
1916 serialize_dynamic_with_shape(serializer, elem_dyn, item_shape, value_shape)?;
1917 }
1918 }
1919
1920 serializer.end_seq().map_err(SerializeError::Backend)
1921}
1922
1923fn serialize_array_from_dynamic<S>(
1924 serializer: &mut S,
1925 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
1926 item_shape: &'static Shape,
1927 value_shape: &'static Shape,
1928) -> Result<(), SerializeError<S::Error>>
1929where
1930 S: FormatSerializer,
1931{
1932 serializer.begin_seq().map_err(SerializeError::Backend)?;
1934
1935 if let Some(iter) = dynamic.array_iter() {
1936 for elem in iter {
1937 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
1938 SerializeError::Internal(Cow::Borrowed("array element is not a dynamic value"))
1939 })?;
1940 serialize_dynamic_with_shape(serializer, elem_dyn, item_shape, value_shape)?;
1941 }
1942 }
1943
1944 serializer.end_seq().map_err(SerializeError::Backend)
1945}
1946
1947fn serialize_map_from_dynamic<S>(
1948 serializer: &mut S,
1949 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
1950 key_shape: &'static Shape,
1951 value_shape_inner: &'static Shape,
1952 value_shape: &'static Shape,
1953) -> Result<(), SerializeError<S::Error>>
1954where
1955 S: FormatSerializer,
1956{
1957 let len = dynamic.object_len().ok_or_else(|| {
1958 SerializeError::Unsupported(Cow::Borrowed("expected object value for map target shape"))
1959 })?;
1960
1961 match serializer.map_encoding() {
1962 MapEncoding::Pairs => {
1963 serializer
1964 .begin_map_with_len(len)
1965 .map_err(SerializeError::Backend)?;
1966
1967 if let Some(iter) = dynamic.object_iter() {
1968 for (key, val) in iter {
1969 serialize_string_as_scalar(serializer, key, key_shape)?;
1971 let val_dyn = val.into_dynamic_value().map_err(|_| {
1973 SerializeError::Internal(Cow::Borrowed(
1974 "object value is not a dynamic value",
1975 ))
1976 })?;
1977 serialize_dynamic_with_shape(
1978 serializer,
1979 val_dyn,
1980 value_shape_inner,
1981 value_shape,
1982 )?;
1983 }
1984 }
1985
1986 serializer.end_map().map_err(SerializeError::Backend)
1987 }
1988 MapEncoding::Struct => {
1989 serializer.begin_struct().map_err(SerializeError::Backend)?;
1990
1991 if let Some(iter) = dynamic.object_iter() {
1992 for (key, val) in iter {
1993 serializer.field_key(key).map_err(SerializeError::Backend)?;
1994 let val_dyn = val.into_dynamic_value().map_err(|_| {
1995 SerializeError::Internal(Cow::Borrowed(
1996 "object value is not a dynamic value",
1997 ))
1998 })?;
1999 serialize_dynamic_with_shape(
2000 serializer,
2001 val_dyn,
2002 value_shape_inner,
2003 value_shape,
2004 )?;
2005 }
2006 }
2007
2008 serializer.end_struct().map_err(SerializeError::Backend)
2009 }
2010 }
2011}
2012
2013fn serialize_string_as_scalar<S>(
2014 serializer: &mut S,
2015 s: &str,
2016 _key_shape: &'static Shape,
2017) -> Result<(), SerializeError<S::Error>>
2018where
2019 S: FormatSerializer,
2020{
2021 serializer
2024 .scalar(ScalarValue::Str(Cow::Borrowed(s)))
2025 .map_err(SerializeError::Backend)
2026}
2027
2028fn serialize_scalar_from_dynamic<S>(
2029 serializer: &mut S,
2030 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2031 scalar_type: facet_core::ScalarType,
2032) -> Result<(), SerializeError<S::Error>>
2033where
2034 S: FormatSerializer,
2035{
2036 use facet_core::ScalarType as ST;
2037
2038 match scalar_type {
2039 ST::Unit => serializer
2040 .scalar(ScalarValue::Null)
2041 .map_err(SerializeError::Backend),
2042 ST::Bool => {
2043 let v = dynamic
2044 .as_bool()
2045 .ok_or_else(|| SerializeError::Unsupported(Cow::Borrowed("expected bool value")))?;
2046 serializer
2047 .scalar(ScalarValue::Bool(v))
2048 .map_err(SerializeError::Backend)
2049 }
2050 ST::Char => {
2051 let s = dynamic.as_str().ok_or_else(|| {
2052 SerializeError::Unsupported(Cow::Borrowed("expected string value for char"))
2053 })?;
2054 let c = s.chars().next().ok_or_else(|| {
2055 SerializeError::Unsupported(Cow::Borrowed("expected non-empty string for char"))
2056 })?;
2057 serializer
2058 .scalar(ScalarValue::Char(c))
2059 .map_err(SerializeError::Backend)
2060 }
2061 ST::Str | ST::String | ST::CowStr => {
2062 let s = dynamic.as_str().ok_or_else(|| {
2063 SerializeError::Unsupported(Cow::Borrowed("expected string value"))
2064 })?;
2065 serializer
2066 .scalar(ScalarValue::Str(Cow::Borrowed(s)))
2067 .map_err(SerializeError::Backend)
2068 }
2069 ST::U8 | ST::U16 | ST::U32 | ST::U64 | ST::USize => {
2070 let n = dynamic.as_u64().ok_or_else(|| {
2071 SerializeError::Unsupported(Cow::Borrowed("expected unsigned integer value"))
2072 })?;
2073 serializer
2074 .scalar(ScalarValue::U64(n))
2075 .map_err(SerializeError::Backend)
2076 }
2077 ST::U128 => {
2078 let n = dynamic.as_u64().ok_or_else(|| {
2079 SerializeError::Unsupported(Cow::Borrowed("expected unsigned integer value"))
2080 })?;
2081 serializer
2082 .scalar(ScalarValue::U128(n as u128))
2083 .map_err(SerializeError::Backend)
2084 }
2085 ST::I8 | ST::I16 | ST::I32 | ST::I64 | ST::ISize => {
2086 let n = dynamic.as_i64().ok_or_else(|| {
2087 SerializeError::Unsupported(Cow::Borrowed("expected signed integer value"))
2088 })?;
2089 serializer
2090 .scalar(ScalarValue::I64(n))
2091 .map_err(SerializeError::Backend)
2092 }
2093 ST::I128 => {
2094 let n = dynamic.as_i64().ok_or_else(|| {
2095 SerializeError::Unsupported(Cow::Borrowed("expected signed integer value"))
2096 })?;
2097 serializer
2098 .scalar(ScalarValue::I128(n as i128))
2099 .map_err(SerializeError::Backend)
2100 }
2101 ST::F32 | ST::F64 => {
2102 let n = dynamic.as_f64().ok_or_else(|| {
2103 SerializeError::Unsupported(Cow::Borrowed("expected float value"))
2104 })?;
2105 serializer
2106 .scalar(ScalarValue::F64(n))
2107 .map_err(SerializeError::Backend)
2108 }
2109 _ => Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2110 "unsupported scalar type: {:?}",
2111 scalar_type
2112 )))),
2113 }
2114}
2115
2116fn serialize_struct_from_dynamic<S>(
2117 serializer: &mut S,
2118 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2119 struct_def: facet_core::StructType,
2120 value_shape: &'static Shape,
2121) -> Result<(), SerializeError<S::Error>>
2122where
2123 S: FormatSerializer,
2124{
2125 let is_tuple = matches!(struct_def.kind, StructKind::Tuple | StructKind::TupleStruct);
2126
2127 if is_tuple {
2128 serializer.begin_seq().map_err(SerializeError::Backend)?;
2130
2131 let iter = dynamic.array_iter().ok_or_else(|| {
2132 SerializeError::Unsupported(Cow::Borrowed("expected array value for tuple"))
2133 })?;
2134
2135 for (field, elem) in struct_def.fields.iter().zip(iter) {
2136 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2137 SerializeError::Internal(Cow::Borrowed("tuple element is not a dynamic value"))
2138 })?;
2139 serialize_dynamic_with_shape(serializer, elem_dyn, field.shape(), value_shape)?;
2140 }
2141
2142 serializer.end_seq().map_err(SerializeError::Backend)
2143 } else {
2144 let field_mode = serializer.struct_field_mode();
2146
2147 serializer.begin_struct().map_err(SerializeError::Backend)?;
2148
2149 for field in struct_def.fields {
2150 if field.is_metadata() {
2152 continue;
2153 }
2154
2155 let field_name = field.name;
2156 let field_value = dynamic.object_get(field_name).ok_or_else(|| {
2157 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2158 "missing field '{}' in object",
2159 field_name
2160 )))
2161 })?;
2162
2163 if field_mode == StructFieldMode::Named {
2164 serializer
2165 .field_key(field_name)
2166 .map_err(SerializeError::Backend)?;
2167 }
2168
2169 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
2170 SerializeError::Internal(Cow::Borrowed("field value is not a dynamic value"))
2171 })?;
2172 serialize_dynamic_with_shape(serializer, field_dyn, field.shape(), value_shape)?;
2173 }
2174
2175 serializer.end_struct().map_err(SerializeError::Backend)
2176 }
2177}
2178
2179fn serialize_enum_from_dynamic<S>(
2180 serializer: &mut S,
2181 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2182 enum_def: facet_core::EnumType,
2183 target_shape: &'static Shape,
2184 value_shape: &'static Shape,
2185) -> Result<(), SerializeError<S::Error>>
2186where
2187 S: FormatSerializer,
2188{
2189 let use_index = serializer.enum_variant_encoding() == EnumVariantEncoding::Index;
2195
2196 match dynamic.kind() {
2197 DynValueKind::String => {
2199 let variant_name = dynamic.as_str().ok_or_else(|| {
2200 SerializeError::Internal(Cow::Borrowed("expected string for unit variant"))
2201 })?;
2202
2203 let (variant_index, variant) = enum_def
2204 .variants
2205 .iter()
2206 .enumerate()
2207 .find(|(_, v)| v.effective_name() == variant_name)
2208 .ok_or_else(|| {
2209 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2210 "unknown variant '{}'",
2211 variant_name
2212 )))
2213 })?;
2214
2215 if use_index {
2216 serializer
2217 .begin_enum_variant(variant_index, variant.effective_name())
2218 .map_err(SerializeError::Backend)?;
2219 Ok(())
2221 } else {
2222 serializer
2223 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
2224 .map_err(SerializeError::Backend)
2225 }
2226 }
2227
2228 DynValueKind::Object => {
2230 let obj_len = dynamic.object_len().unwrap_or(0);
2232 if obj_len != 1 {
2233 return Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2234 "expected single-key object for enum variant, got {} keys",
2235 obj_len
2236 ))));
2237 }
2238
2239 let (variant_name, payload) = dynamic.object_get_entry(0).ok_or_else(|| {
2240 SerializeError::Internal(Cow::Borrowed("expected object entry for enum variant"))
2241 })?;
2242
2243 let (variant_index, variant) = enum_def
2244 .variants
2245 .iter()
2246 .enumerate()
2247 .find(|(_, v)| v.effective_name() == variant_name)
2248 .ok_or_else(|| {
2249 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2250 "unknown variant '{}'",
2251 variant_name
2252 )))
2253 })?;
2254
2255 let payload_dyn = payload.into_dynamic_value().map_err(|_| {
2256 SerializeError::Internal(Cow::Borrowed("variant payload is not a dynamic value"))
2257 })?;
2258
2259 if use_index {
2260 serializer
2261 .begin_enum_variant(variant_index, variant.effective_name())
2262 .map_err(SerializeError::Backend)?;
2263
2264 match variant.data.kind {
2266 StructKind::Unit => {
2267 }
2269 StructKind::TupleStruct | StructKind::Tuple => {
2270 if variant.data.fields.len() == 1 {
2271 serialize_dynamic_with_shape(
2273 serializer,
2274 payload_dyn,
2275 variant.data.fields[0].shape(),
2276 value_shape,
2277 )?;
2278 } else {
2279 let iter = payload_dyn.array_iter().ok_or_else(|| {
2281 SerializeError::Unsupported(Cow::Borrowed(
2282 "expected array for tuple variant payload",
2283 ))
2284 })?;
2285
2286 for (field, elem) in variant.data.fields.iter().zip(iter) {
2287 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2288 SerializeError::Internal(Cow::Borrowed(
2289 "tuple element is not a dynamic value",
2290 ))
2291 })?;
2292 serialize_dynamic_with_shape(
2293 serializer,
2294 elem_dyn,
2295 field.shape(),
2296 value_shape,
2297 )?;
2298 }
2299 }
2300 }
2301 StructKind::Struct => {
2302 for field in variant.data.fields {
2304 let field_value =
2305 payload_dyn.object_get(field.name).ok_or_else(|| {
2306 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2307 "missing field '{}' in struct variant",
2308 field.name
2309 )))
2310 })?;
2311 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
2312 SerializeError::Internal(Cow::Borrowed(
2313 "field value is not a dynamic value",
2314 ))
2315 })?;
2316 serialize_dynamic_with_shape(
2317 serializer,
2318 field_dyn,
2319 field.shape(),
2320 value_shape,
2321 )?;
2322 }
2323 }
2324 }
2325
2326 Ok(())
2327 } else {
2328 serializer.begin_struct().map_err(SerializeError::Backend)?;
2330 serializer
2331 .field_key(variant.effective_name())
2332 .map_err(SerializeError::Backend)?;
2333
2334 match variant.data.kind {
2335 StructKind::Unit => {
2336 serializer
2337 .scalar(ScalarValue::Null)
2338 .map_err(SerializeError::Backend)?;
2339 }
2340 StructKind::TupleStruct | StructKind::Tuple => {
2341 if variant.data.fields.len() == 1 {
2342 serialize_dynamic_with_shape(
2343 serializer,
2344 payload_dyn,
2345 variant.data.fields[0].shape(),
2346 value_shape,
2347 )?;
2348 } else {
2349 serializer.begin_seq().map_err(SerializeError::Backend)?;
2350 let iter = payload_dyn.array_iter().ok_or_else(|| {
2351 SerializeError::Unsupported(Cow::Borrowed(
2352 "expected array for tuple variant",
2353 ))
2354 })?;
2355 for (field, elem) in variant.data.fields.iter().zip(iter) {
2356 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2357 SerializeError::Internal(Cow::Borrowed(
2358 "element is not a dynamic value",
2359 ))
2360 })?;
2361 serialize_dynamic_with_shape(
2362 serializer,
2363 elem_dyn,
2364 field.shape(),
2365 value_shape,
2366 )?;
2367 }
2368 serializer.end_seq().map_err(SerializeError::Backend)?;
2369 }
2370 }
2371 StructKind::Struct => {
2372 serializer.begin_struct().map_err(SerializeError::Backend)?;
2373 for field in variant.data.fields {
2374 let field_value =
2375 payload_dyn.object_get(field.name).ok_or_else(|| {
2376 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2377 "missing field '{}'",
2378 field.name
2379 )))
2380 })?;
2381 serializer
2382 .field_key(field.name)
2383 .map_err(SerializeError::Backend)?;
2384 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
2385 SerializeError::Internal(Cow::Borrowed(
2386 "field is not a dynamic value",
2387 ))
2388 })?;
2389 serialize_dynamic_with_shape(
2390 serializer,
2391 field_dyn,
2392 field.shape(),
2393 value_shape,
2394 )?;
2395 }
2396 serializer.end_struct().map_err(SerializeError::Backend)?;
2397 }
2398 }
2399
2400 serializer.end_struct().map_err(SerializeError::Backend)
2401 }
2402 }
2403
2404 DynValueKind::Null => {
2406 if let Some((variant_index, variant)) = enum_def
2409 .variants
2410 .iter()
2411 .enumerate()
2412 .find(|(_, v)| v.name.eq_ignore_ascii_case("null") || v.name == "None")
2413 {
2414 if use_index {
2415 serializer
2416 .begin_enum_variant(variant_index, variant.effective_name())
2417 .map_err(SerializeError::Backend)?;
2418 Ok(())
2419 } else {
2420 serializer
2421 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
2422 .map_err(SerializeError::Backend)
2423 }
2424 } else {
2425 Err(SerializeError::Unsupported(Cow::Borrowed(
2426 "null value for enum without null/None variant",
2427 )))
2428 }
2429 }
2430
2431 _ => {
2432 let _ = target_shape; Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2436 "unsupported dynamic value kind {:?} for enum serialization",
2437 dynamic.kind()
2438 ))))
2439 }
2440 }
2441}