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