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