1extern crate alloc;
2
3use alloc::borrow::Cow;
4use alloc::string::{String, ToString};
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 fn map_key_string<'mem, 'facet>(
951 &self,
952 key: Peek<'mem, 'facet>,
953 ) -> Result<Cow<'mem, str>, SerializeError<S::Error>> {
954 if let Some(proxy_def) = key
955 .shape()
956 .effective_proxy(self.serializer.format_namespace())
957 {
958 let proxy = key
959 .custom_serialization_with_proxy(proxy_def)
960 .map_err(|err| SerializeError::Unsupported(Cow::Owned(alloc::format!("{err}"))))?;
961 let proxy_peek = proxy.as_peek().innermost_peek();
962 let key = extract_string_from_peek(proxy_peek)
963 .map(ToString::to_string)
964 .unwrap_or_else(|| alloc::format!("{}", proxy_peek));
965 return Ok(Cow::Owned(key));
966 }
967
968 Ok(extract_string_from_peek(key)
969 .map(Cow::Borrowed)
970 .unwrap_or_else(|| Cow::Owned(alloc::format!("{}", key))))
971 }
972
973 #[inline(never)]
974 fn serialize_map_as_pairs<'mem, 'facet>(
975 &mut self,
976 map: PeekMap<'mem, 'facet>,
977 len: usize,
978 ) -> Result<(), SerializeError<S::Error>> {
979 self.serializer
980 .begin_map_with_len(len)
981 .map_err(SerializeError::Backend)?;
982 for (key, val) in map.iter() {
983 self.serialize_impl(key)?;
984 let key_str = self.map_key_string(key)?.into_owned();
985 self.push(PathSegment::Field(Cow::Owned(key_str)));
986 self.serialize_impl(val)?;
987 self.pop();
988 }
989 self.serializer.end_map().map_err(SerializeError::Backend)
990 }
991
992 #[inline(never)]
993 fn serialize_map_as_struct<'mem, 'facet>(
994 &mut self,
995 map: PeekMap<'mem, 'facet>,
996 ) -> Result<(), SerializeError<S::Error>> {
997 self.serializer
998 .begin_struct()
999 .map_err(SerializeError::Backend)?;
1000 for (key, val) in map.iter() {
1001 let key_str = self.map_key_string(key)?;
1002 if !self
1003 .serializer
1004 .serialize_map_key(key)
1005 .map_err(SerializeError::Backend)?
1006 {
1007 self.serializer
1008 .field_key(&key_str)
1009 .map_err(SerializeError::Backend)?;
1010 }
1011 self.push(PathSegment::Field(Cow::Owned(key_str.into_owned())));
1012 self.serialize_impl(val)?;
1013 self.pop();
1014 }
1015 self.serializer
1016 .end_struct()
1017 .map_err(SerializeError::Backend)
1018 }
1019
1020 #[inline(never)]
1021 fn serialize_set<'mem, 'facet>(
1022 &mut self,
1023 set: PeekSet<'mem, 'facet>,
1024 ) -> Result<(), SerializeError<S::Error>> {
1025 let len = set.len();
1026 self.serializer
1027 .begin_seq_with_len(len)
1028 .map_err(SerializeError::Backend)?;
1029 for (idx, item) in set.iter().enumerate() {
1030 self.push(PathSegment::Index(idx));
1031 self.serialize_impl(item)?;
1032 self.pop();
1033 }
1034 self.serializer.end_seq().map_err(SerializeError::Backend)
1035 }
1036
1037 fn serialize_field_value<'mem, 'facet>(
1038 &mut self,
1039 field_item: &facet_reflect::FieldItem,
1040 field_value: Peek<'mem, 'facet>,
1041 ) -> Result<(), SerializeError<S::Error>> {
1042 self.with_field_context(field_item.field, |this| {
1043 if let Some(proxy_def) = field_item
1044 .field
1045 .and_then(|f| f.effective_proxy(this.serializer.format_namespace()))
1046 {
1047 this.serialize_via_proxy(field_value, proxy_def)
1048 } else {
1049 this.serialize_impl(field_value)
1050 }
1051 })
1052 }
1053
1054 fn serialize_struct<'mem, 'facet>(
1055 &mut self,
1056 shape: &'static Shape,
1057 struct_: facet_reflect::PeekStruct<'mem, 'facet>,
1058 ) -> Result<(), SerializeError<S::Error>> {
1059 let kind = struct_.ty().kind;
1060 self.serializer
1061 .struct_metadata(shape)
1062 .map_err(SerializeError::Backend)?;
1063
1064 if kind == StructKind::Tuple || kind == StructKind::TupleStruct {
1065 self.serialize_tuple_struct(shape, struct_)
1066 } else {
1067 self.serialize_named_struct(struct_)
1068 }
1069 }
1070
1071 #[inline(never)]
1072 fn serialize_tuple_struct<'mem, 'facet>(
1073 &mut self,
1074 shape: &'static Shape,
1075 struct_: facet_reflect::PeekStruct<'mem, 'facet>,
1076 ) -> Result<(), SerializeError<S::Error>> {
1077 let fields: alloc::vec::Vec<_> = struct_.fields_for_binary_serialize().collect();
1078 let is_transparent = shape.is_transparent() && fields.len() == 1;
1079
1080 if is_transparent {
1081 let (field_item, field_value) = &fields[0];
1082 self.serialize_field_value(field_item, *field_value)
1083 } else {
1084 self.serializer
1085 .begin_seq()
1086 .map_err(SerializeError::Backend)?;
1087 for (idx, (field_item, field_value)) in fields.into_iter().enumerate() {
1088 self.push(PathSegment::Index(idx));
1089 self.serialize_field_value(&field_item, field_value)?;
1090 self.pop();
1091 }
1092 self.serializer.end_seq().map_err(SerializeError::Backend)
1093 }
1094 }
1095
1096 #[inline(never)]
1097 fn serialize_named_struct<'mem, 'facet>(
1098 &mut self,
1099 struct_: facet_reflect::PeekStruct<'mem, 'facet>,
1100 ) -> Result<(), SerializeError<S::Error>> {
1101 let field_mode = self.serializer.struct_field_mode();
1102 self.serializer
1103 .begin_struct()
1104 .map_err(SerializeError::Backend)?;
1105
1106 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1107 struct_.fields_for_binary_serialize().collect()
1108 } else {
1109 struct_.fields_for_serialize().collect()
1110 };
1111
1112 sort_fields_if_needed(self.serializer, &mut fields);
1113
1114 for (field_item, field_value) in fields {
1115 if self.serializer.should_omit_field(&field_item, field_value) {
1116 continue;
1117 }
1118 if field_item.flattened {
1119 self.serialize_flattened_struct_field(field_mode, field_item, field_value)?;
1120 } else {
1121 self.serialize_regular_struct_field(field_mode, field_item, field_value)?;
1122 }
1123 }
1124
1125 self.serializer
1126 .end_struct()
1127 .map_err(SerializeError::Backend)
1128 }
1129
1130 #[inline(never)]
1131 fn serialize_regular_struct_field<'mem, 'facet>(
1132 &mut self,
1133 field_mode: StructFieldMode,
1134 field_item: facet_reflect::FieldItem,
1135 field_value: Peek<'mem, 'facet>,
1136 ) -> Result<(), SerializeError<S::Error>> {
1137 let key_written = self
1138 .serializer
1139 .field_metadata_with_value(&field_item, field_value)
1140 .map_err(SerializeError::Backend)?;
1141 if !key_written {
1142 self.serializer
1143 .field_metadata(&field_item)
1144 .map_err(SerializeError::Backend)?;
1145 if field_mode == StructFieldMode::Named {
1146 self.serializer
1147 .field_key(field_item.effective_name())
1148 .map_err(SerializeError::Backend)?;
1149 }
1150 }
1151 self.push(PathSegment::Field(Cow::Owned(
1152 field_item.effective_name().to_string(),
1153 )));
1154 let result = self.serialize_field_value(&field_item, field_value);
1155 self.pop();
1156 result
1157 }
1158
1159 #[inline(never)]
1160 fn serialize_flattened_struct_field<'mem, 'facet>(
1161 &mut self,
1162 field_mode: StructFieldMode,
1163 field_item: facet_reflect::FieldItem,
1164 field_value: Peek<'mem, 'facet>,
1165 ) -> Result<(), SerializeError<S::Error>> {
1166 if let Some(field) = field_item.field
1167 && let shape = field.shape()
1168 && let Some(tag_key) = shape.get_tag_attr()
1169 && shape.get_content_attr().is_none()
1170 {
1171 let variant_name = field_item.effective_name();
1172
1173 if field_mode == StructFieldMode::Named {
1174 self.serializer
1175 .field_key(tag_key)
1176 .map_err(SerializeError::Backend)?;
1177 }
1178 self.serializer
1179 .scalar(ScalarValue::Str(Cow::Borrowed(variant_name)))
1180 .map_err(SerializeError::Backend)?;
1181
1182 if let Ok(inner_struct) = field_value.into_struct() {
1183 for (inner_item, inner_value) in inner_struct.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 let Ok(enum_peek) = field_value.into_enum() {
1196 for (inner_item, inner_value) in enum_peek.fields_for_serialize() {
1197 if field_mode == StructFieldMode::Named {
1198 self.serializer
1199 .field_key(inner_item.effective_name())
1200 .map_err(SerializeError::Backend)?;
1201 }
1202 self.push(PathSegment::Field(Cow::Owned(
1203 inner_item.effective_name().to_string(),
1204 )));
1205 self.serialize_field_value(&inner_item, inner_value)?;
1206 self.pop();
1207 }
1208 } else if matches!(field_value.shape().ty, Type::Primitive(_)) {
1209 return Err(SerializeError::Unsupported(
1210 "internally-tagged enum with scalar newtype payload cannot be \
1211 flattened; use #[facet(content = \"...\")] for adjacently-tagged \
1212 representation"
1213 .into(),
1214 ));
1215 }
1216 return Ok(());
1217 }
1218
1219 if {
1220 let shape = field_value.shape();
1221 shape.get_tag_attr().is_none() && shape.get_content_attr().is_none()
1222 } && let Ok(enum_peek) = field_value.into_enum()
1223 {
1224 if field_mode == StructFieldMode::Named {
1225 self.serializer
1226 .field_key(field_item.effective_name())
1227 .map_err(SerializeError::Backend)?;
1228 }
1229
1230 let variant = enum_peek
1231 .active_variant()
1232 .map_err(|e| SerializeError::Unsupported(Cow::Owned(e.to_string())))?;
1233
1234 self.push(PathSegment::Variant(Cow::Owned(
1235 field_item.effective_name().to_string(),
1236 )));
1237 if variant.data.kind == StructKind::Unit {
1238 self.serializer
1239 .serialize_none()
1240 .map_err(SerializeError::Backend)?;
1241 } else {
1242 self.serialize_variant_after_tag(enum_peek, variant)?;
1243 }
1244 self.pop();
1245 return Ok(());
1246 }
1247
1248 self.serialize_regular_struct_field(field_mode, field_item, field_value)
1249 }
1250
1251 fn serialize_flattened_newtype_value<'mem, 'facet>(
1261 &mut self,
1262 value: Peek<'mem, 'facet>,
1263 used_tag_keys: &[&str],
1264 ) -> Result<(), SerializeError<S::Error>> {
1265 let shape = value.shape();
1266 let field_mode = self.serializer.struct_field_mode();
1267
1268 if let Ok(struct_) = value.into_struct() {
1270 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1271 struct_.fields_for_binary_serialize().collect()
1272 } else {
1273 struct_.fields_for_serialize().collect()
1274 };
1275 sort_fields_if_needed(self.serializer, &mut fields);
1276 for (field_item, field_value) in fields {
1277 self.serializer
1278 .field_metadata(&field_item)
1279 .map_err(SerializeError::Backend)?;
1280 if field_mode == StructFieldMode::Named {
1281 self.serializer
1282 .field_key(field_item.effective_name())
1283 .map_err(SerializeError::Backend)?;
1284 }
1285 self.push(PathSegment::Field(Cow::Owned(
1286 field_item.effective_name().to_string(),
1287 )));
1288 self.serialize_field_value(&field_item, field_value)?;
1289 self.pop();
1290 }
1291 return Ok(());
1292 }
1293
1294 if let Some(inner_tag) = shape.get_tag_attr()
1296 && shape.get_content_attr().is_none()
1297 && let Ok(inner_enum) = value.into_enum()
1298 {
1299 if used_tag_keys.contains(&inner_tag) {
1304 return Err(SerializeError::Unsupported(
1305 format!(
1306 "nested internally-tagged enums use the same tag key \"{}\"; \
1307 this is ambiguous when flattened into a single object",
1308 inner_tag
1309 )
1310 .into(),
1311 ));
1312 }
1313
1314 let inner_variant = inner_enum
1315 .active_variant()
1316 .map_err(|e| SerializeError::Unsupported(Cow::Owned(e.to_string())))?;
1317
1318 self.serializer
1320 .field_key(inner_tag)
1321 .map_err(SerializeError::Backend)?;
1322 self.serializer
1323 .scalar(ScalarValue::Str(Cow::Borrowed(
1324 inner_variant.effective_name(),
1325 )))
1326 .map_err(SerializeError::Backend)?;
1327
1328 self.push(PathSegment::Variant(Cow::Borrowed(
1329 inner_variant.effective_name(),
1330 )));
1331
1332 match inner_variant.data.kind {
1333 StructKind::Unit => {}
1334 StructKind::Struct => {
1335 let mut inner_fields: alloc::vec::Vec<_> =
1336 if field_mode == StructFieldMode::Unnamed {
1337 inner_enum.fields_for_binary_serialize().collect()
1338 } else {
1339 inner_enum.fields_for_serialize().collect()
1340 };
1341 sort_fields_if_needed(self.serializer, &mut inner_fields);
1342
1343 for (field_item, field_value) in inner_fields {
1344 self.serializer
1345 .field_metadata(&field_item)
1346 .map_err(SerializeError::Backend)?;
1347 if field_mode == StructFieldMode::Named {
1348 self.serializer
1349 .field_key(field_item.effective_name())
1350 .map_err(SerializeError::Backend)?;
1351 }
1352 self.push(PathSegment::Field(Cow::Owned(
1353 field_item.effective_name().to_string(),
1354 )));
1355 self.serialize_field_value(&field_item, field_value)?;
1356 self.pop();
1357 }
1358 }
1359 StructKind::TupleStruct | StructKind::Tuple => {
1360 if inner_variant.data.fields.len() != 1 {
1362 self.pop();
1363 return Err(SerializeError::Unsupported(Cow::Borrowed(
1364 "internally tagged tuple variants with multiple fields are not supported",
1365 )));
1366 }
1367 let nested_value = inner_enum
1368 .field(0)
1369 .map_err(|e| SerializeError::Unsupported(Cow::Owned(e.to_string())))?
1370 .expect("single-field tuple variant should have field 0");
1371 let mut inner_used_tag_keys = alloc::vec::Vec::from(used_tag_keys);
1372 inner_used_tag_keys.push(inner_tag);
1373 self.serialize_flattened_newtype_value(nested_value, &inner_used_tag_keys)?;
1374 }
1375 }
1376
1377 self.pop();
1378 return Ok(());
1379 }
1380
1381 Err(SerializeError::Unsupported(
1383 "internally-tagged enum with scalar newtype payload cannot be \
1384 flattened; use #[facet(content = \"...\")] for adjacently-tagged \
1385 representation"
1386 .into(),
1387 ))
1388 }
1389
1390 fn serialize_discriminant<'mem, 'facet>(
1391 &mut self,
1392 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1393 ) -> Result<(), SerializeError<S::Error>> {
1394 match enum_.ty().enum_repr {
1395 facet_core::EnumRepr::Rust => Err(SerializeError::Internal(Cow::Borrowed(
1396 "enum does not have an explicit representation",
1397 ))),
1398 facet_core::EnumRepr::RustNPO
1399 | facet_core::EnumRepr::U8
1400 | facet_core::EnumRepr::U16
1401 | facet_core::EnumRepr::U32
1402 | facet_core::EnumRepr::U64
1403 | facet_core::EnumRepr::USize => self
1404 .serializer
1405 .scalar(ScalarValue::U64(enum_.discriminant() as u64))
1406 .map_err(SerializeError::Backend),
1407 facet_core::EnumRepr::I8
1408 | facet_core::EnumRepr::I16
1409 | facet_core::EnumRepr::I32
1410 | facet_core::EnumRepr::I64
1411 | facet_core::EnumRepr::ISize => self
1412 .serializer
1413 .scalar(ScalarValue::I64(enum_.discriminant()))
1414 .map_err(SerializeError::Backend),
1415 }
1416 }
1417
1418 fn serialize_enum<'mem, 'facet>(
1419 &mut self,
1420 shape: &'static Shape,
1421 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1422 ) -> Result<(), SerializeError<S::Error>> {
1423 let variant = enum_.active_variant().map_err(|_| {
1424 SerializeError::Unsupported(Cow::Borrowed("opaque enum layout is unsupported"))
1425 })?;
1426
1427 self.serializer
1428 .variant_metadata(variant)
1429 .map_err(SerializeError::Backend)?;
1430
1431 if shape.is_cow() {
1433 let inner = enum_
1434 .field(0)
1435 .map_err(|_| {
1436 SerializeError::Internal(Cow::Borrowed("cow variant field lookup failed"))
1437 })?
1438 .ok_or(SerializeError::Internal(Cow::Borrowed(
1439 "cow variant has no field",
1440 )))?;
1441 return self.serialize_impl(inner);
1442 }
1443
1444 if self.serializer.enum_variant_encoding() == EnumVariantEncoding::Index {
1445 let variant_index = enum_.variant_index().map_err(|_| {
1446 SerializeError::Unsupported(Cow::Borrowed("opaque enum layout is unsupported"))
1447 })?;
1448 self.serializer
1449 .begin_enum_variant(variant_index, variant.name)
1450 .map_err(SerializeError::Backend)?;
1451
1452 self.push(PathSegment::Variant(Cow::Borrowed(variant.name)));
1453 let result = match variant.data.kind {
1454 StructKind::Unit => Ok(()),
1455 StructKind::TupleStruct | StructKind::Tuple | StructKind::Struct => {
1456 for (idx, (field_item, field_value)) in
1457 enum_.fields_for_binary_serialize().enumerate()
1458 {
1459 self.push(PathSegment::Index(idx));
1460 self.serialize_field_value(&field_item, field_value)?;
1461 self.pop();
1462 }
1463 Ok(())
1464 }
1465 };
1466 self.pop();
1467 return result;
1468 }
1469
1470 let numeric = shape.is_numeric();
1471 let untagged = shape.is_untagged();
1472 let tag = shape.get_tag_attr();
1473 let content = shape.get_content_attr();
1474
1475 if numeric && tag.is_none() {
1476 return serialize_numeric_enum(self.serializer, variant);
1477 }
1478 if untagged || variant.has_builtin_attr("untagged") {
1479 self.push(PathSegment::Variant(Cow::Borrowed(
1480 variant.effective_name(),
1481 )));
1482 let result = self.serialize_untagged_enum(enum_, variant);
1483 self.pop();
1484 return result;
1485 }
1486
1487 if variant.is_other() {
1491 let has_tag_field = variant.data.fields.iter().any(|f| f.is_variant_tag());
1492 if !has_tag_field {
1493 self.push(PathSegment::Variant(Cow::Borrowed(
1494 variant.effective_name(),
1495 )));
1496 let result = self.serialize_untagged_enum(enum_, variant);
1497 self.pop();
1498 return result;
1499 }
1500 }
1501
1502 match (tag, content) {
1503 (Some(tag_key), None) => {
1504 self.serializer
1506 .begin_struct()
1507 .map_err(SerializeError::Backend)?;
1508 self.serializer
1509 .field_key(tag_key)
1510 .map_err(SerializeError::Backend)?;
1511
1512 if numeric {
1513 self.serialize_discriminant(enum_)?;
1514 } else {
1515 self.serializer
1516 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1517 .map_err(SerializeError::Backend)?;
1518 }
1519
1520 self.push(PathSegment::Variant(Cow::Borrowed(
1521 variant.effective_name(),
1522 )));
1523 let field_mode = self.serializer.struct_field_mode();
1524 match variant.data.kind {
1525 StructKind::Unit => {}
1526 StructKind::Struct => {
1527 let mut fields: alloc::vec::Vec<_> =
1528 if field_mode == StructFieldMode::Unnamed {
1529 enum_.fields_for_binary_serialize().collect()
1530 } else {
1531 enum_.fields_for_serialize().collect()
1532 };
1533 sort_fields_if_needed(self.serializer, &mut fields);
1534 for (field_item, field_value) in fields {
1535 self.serializer
1536 .field_metadata(&field_item)
1537 .map_err(SerializeError::Backend)?;
1538 if field_mode == StructFieldMode::Named {
1539 self.serializer
1540 .field_key(field_item.effective_name())
1541 .map_err(SerializeError::Backend)?;
1542 }
1543 self.push(PathSegment::Field(Cow::Owned(
1544 field_item.effective_name().to_string(),
1545 )));
1546 self.serialize_field_value(&field_item, field_value)?;
1547 self.pop();
1548 }
1549 }
1550 StructKind::TupleStruct | StructKind::Tuple => {
1551 if variant.data.fields.len() != 1 {
1556 self.pop();
1557 return Err(SerializeError::Unsupported(Cow::Borrowed(
1558 "internally tagged tuple variants with multiple fields are not supported",
1559 )));
1560 }
1561
1562 let inner_value = enum_
1563 .field(0)
1564 .map_err(|e| SerializeError::Unsupported(Cow::Owned(e.to_string())))?
1565 .expect("single-field tuple variant should have field 0");
1566
1567 self.serialize_flattened_newtype_value(inner_value, &[tag_key])?;
1568 }
1569 }
1570 self.pop();
1571
1572 self.serializer
1573 .end_struct()
1574 .map_err(SerializeError::Backend)?;
1575 return Ok(());
1576 }
1577 (Some(tag_key), Some(content_key)) => {
1578 return self.serialize_adjacently_tagged_enum(
1580 enum_,
1581 variant,
1582 tag_key,
1583 content_key,
1584 numeric,
1585 );
1586 }
1587 (None, Some(_)) => {
1588 return Err(SerializeError::Unsupported(Cow::Borrowed(
1589 "adjacent content key set without tag key",
1590 )));
1591 }
1592 (None, None) => {}
1593 }
1594
1595 self.serialize_externally_tagged_enum(enum_, variant)
1597 }
1598
1599 fn serialize_adjacently_tagged_enum<'mem, 'facet>(
1600 &mut self,
1601 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1602 variant: &'static facet_core::Variant,
1603 tag_key: &'static str,
1604 content_key: &'static str,
1605 numeric: bool,
1606 ) -> Result<(), SerializeError<S::Error>> {
1607 let field_mode = self.serializer.struct_field_mode();
1608 self.serializer
1609 .begin_struct()
1610 .map_err(SerializeError::Backend)?;
1611 self.serializer
1612 .field_key(tag_key)
1613 .map_err(SerializeError::Backend)?;
1614
1615 if numeric {
1616 self.serialize_discriminant(enum_)?;
1617 } else {
1618 self.serializer
1619 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1620 .map_err(SerializeError::Backend)?;
1621 }
1622
1623 self.push(PathSegment::Variant(Cow::Borrowed(
1624 variant.effective_name(),
1625 )));
1626
1627 match variant.data.kind {
1628 StructKind::Unit => {}
1629 StructKind::Struct => {
1630 self.serializer
1631 .field_key(content_key)
1632 .map_err(SerializeError::Backend)?;
1633 self.serializer
1634 .begin_struct()
1635 .map_err(SerializeError::Backend)?;
1636 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1637 enum_.fields_for_binary_serialize().collect()
1638 } else {
1639 enum_.fields_for_serialize().collect()
1640 };
1641 sort_fields_if_needed(self.serializer, &mut fields);
1642 for (field_item, field_value) in fields {
1643 self.serializer
1644 .field_metadata(&field_item)
1645 .map_err(SerializeError::Backend)?;
1646 if field_mode == StructFieldMode::Named {
1647 self.serializer
1648 .field_key(field_item.effective_name())
1649 .map_err(SerializeError::Backend)?;
1650 }
1651 self.push(PathSegment::Field(Cow::Owned(
1652 field_item.effective_name().to_string(),
1653 )));
1654 self.serialize_field_value(&field_item, field_value)?;
1655 self.pop();
1656 }
1657 self.serializer
1658 .end_struct()
1659 .map_err(SerializeError::Backend)?;
1660 }
1661 StructKind::TupleStruct | StructKind::Tuple => {
1662 self.serializer
1663 .field_key(content_key)
1664 .map_err(SerializeError::Backend)?;
1665
1666 let field_count = variant.data.fields.len();
1667 if field_count == 1 {
1668 let inner = enum_
1669 .field(0)
1670 .map_err(|_| {
1671 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1672 })?
1673 .ok_or(SerializeError::Internal(Cow::Borrowed(
1674 "variant reported 1 field but field(0) returned None",
1675 )))?;
1676 let field_def = variant.data.fields.first().copied();
1677 self.with_field_context(field_def, |this| this.serialize_impl(inner))?;
1678 } else {
1679 self.serializer
1680 .begin_seq()
1681 .map_err(SerializeError::Backend)?;
1682 for idx in 0..field_count {
1683 let inner = enum_
1684 .field(idx)
1685 .map_err(|_| {
1686 SerializeError::Internal(Cow::Borrowed(
1687 "variant field lookup failed",
1688 ))
1689 })?
1690 .ok_or(SerializeError::Internal(Cow::Borrowed(
1691 "variant field missing while iterating tuple fields",
1692 )))?;
1693 self.push(PathSegment::Index(idx));
1694 let field_def = variant.data.fields.get(idx).copied();
1695 self.with_field_context(field_def, |this| this.serialize_impl(inner))?;
1696 self.pop();
1697 }
1698 self.serializer.end_seq().map_err(SerializeError::Backend)?;
1699 }
1700 }
1701 }
1702
1703 self.pop();
1704 self.serializer
1705 .end_struct()
1706 .map_err(SerializeError::Backend)?;
1707 Ok(())
1708 }
1709
1710 fn serialize_externally_tagged_enum<'mem, 'facet>(
1711 &mut self,
1712 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1713 variant: &'static facet_core::Variant,
1714 ) -> Result<(), SerializeError<S::Error>> {
1715 let field_mode = self.serializer.struct_field_mode();
1716
1717 let tag_name: Cow<'_, str> = if variant.is_other() {
1720 let mut tag_value: Option<Cow<'_, str>> = None;
1721 let fields_iter: alloc::boxed::Box<
1722 dyn Iterator<Item = (facet_reflect::FieldItem, facet_reflect::Peek<'_, '_>)>,
1723 > = if field_mode == StructFieldMode::Unnamed {
1724 alloc::boxed::Box::new(enum_.fields_for_binary_serialize())
1725 } else {
1726 alloc::boxed::Box::new(enum_.fields_for_serialize())
1727 };
1728 for (field_item, field_value) in fields_iter {
1729 if let Some(field) = field_item.field
1730 && field.is_variant_tag()
1731 {
1732 if let Ok(opt) = field_value.into_option()
1733 && let Some(inner) = opt.value()
1734 && let Some(s) = inner.as_str()
1735 {
1736 tag_value = Some(Cow::Borrowed(s));
1737 }
1738 break;
1739 }
1740 }
1741 tag_value.unwrap_or_else(|| Cow::Borrowed(variant.effective_name()))
1742 } else {
1743 Cow::Borrowed(variant.effective_name())
1744 };
1745
1746 let use_tag_syntax = self
1748 .serializer
1749 .write_variant_tag(&tag_name)
1750 .map_err(SerializeError::Backend)?;
1751
1752 self.push(PathSegment::Variant(Cow::Owned(tag_name.to_string())));
1753
1754 let result = if use_tag_syntax {
1755 self.serialize_variant_after_tag(enum_, variant)
1756 } else {
1757 self.serialize_standard_externally_tagged(enum_, variant)
1758 };
1759
1760 self.pop();
1761 result
1762 }
1763
1764 fn serialize_variant_after_tag<'mem, 'facet>(
1765 &mut self,
1766 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1767 variant: &'static facet_core::Variant,
1768 ) -> Result<(), SerializeError<S::Error>> {
1769 let field_mode = self.serializer.struct_field_mode();
1770
1771 match variant.data.kind {
1772 StructKind::Unit => {
1773 self.serializer
1774 .finish_variant_tag_unit_payload()
1775 .map_err(SerializeError::Backend)?;
1776 Ok(())
1777 }
1778 StructKind::TupleStruct | StructKind::Tuple => {
1779 let field_count = variant.data.fields.len();
1780 if field_count == 1 {
1781 let inner = enum_
1782 .field(0)
1783 .map_err(|_| {
1784 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1785 })?
1786 .ok_or(SerializeError::Internal(Cow::Borrowed(
1787 "variant reported 1 field but field(0) returned None",
1788 )))?;
1789 if let Some(field_def) = variant.data.fields.first().copied()
1790 && let Some(proxy_def) =
1791 field_def.effective_proxy(self.serializer.format_namespace())
1792 {
1793 self.with_field_context(Some(field_def), |this| {
1794 this.serialize_via_proxy(inner, proxy_def)
1795 })?;
1796 } else {
1797 self.with_field_context(variant.data.fields.first().copied(), |this| {
1798 this.serialize_impl(inner)
1799 })?;
1800 }
1801 } else {
1802 self.serializer
1803 .begin_seq_after_tag()
1804 .map_err(SerializeError::Backend)?;
1805 for idx in 0..field_count {
1806 let inner = enum_
1807 .field(idx)
1808 .map_err(|_| {
1809 SerializeError::Internal(Cow::Borrowed(
1810 "variant field lookup failed",
1811 ))
1812 })?
1813 .ok_or(SerializeError::Internal(Cow::Borrowed(
1814 "variant field missing while iterating tuple fields",
1815 )))?;
1816 self.push(PathSegment::Index(idx));
1817 if let Some(field_def) = variant.data.fields.get(idx).copied()
1818 && let Some(proxy_def) =
1819 field_def.effective_proxy(self.serializer.format_namespace())
1820 {
1821 self.with_field_context(Some(field_def), |this| {
1822 this.serialize_via_proxy(inner, proxy_def)
1823 })?;
1824 } else {
1825 self.with_field_context(
1826 variant.data.fields.get(idx).copied(),
1827 |this| this.serialize_impl(inner),
1828 )?;
1829 }
1830 self.pop();
1831 }
1832 self.serializer.end_seq().map_err(SerializeError::Backend)?;
1833 }
1834 Ok(())
1835 }
1836 StructKind::Struct => {
1837 let is_other = variant.is_other();
1838 let fields_iter: alloc::boxed::Box<
1839 dyn Iterator<Item = (facet_reflect::FieldItem, facet_reflect::Peek<'_, '_>)>,
1840 > = if field_mode == StructFieldMode::Unnamed {
1841 alloc::boxed::Box::new(enum_.fields_for_binary_serialize())
1842 } else {
1843 alloc::boxed::Box::new(enum_.fields_for_serialize())
1844 };
1845 let mut fields: alloc::vec::Vec<_> = fields_iter
1846 .filter(|(field_item, _)| {
1847 if is_other {
1848 field_item
1849 .field
1850 .map(|f| f.metadata_kind().is_none() && !f.is_variant_tag())
1851 .unwrap_or(true)
1852 } else {
1853 true
1854 }
1855 })
1856 .collect();
1857
1858 if fields.is_empty() {
1859 self.serializer
1860 .finish_variant_tag_unit_payload()
1861 .map_err(SerializeError::Backend)?;
1862 return Ok(());
1863 }
1864
1865 self.serializer
1866 .begin_struct_after_tag()
1867 .map_err(SerializeError::Backend)?;
1868 sort_fields_if_needed(self.serializer, &mut fields);
1869 for (field_item, field_value) in fields {
1870 self.serializer
1871 .field_metadata(&field_item)
1872 .map_err(SerializeError::Backend)?;
1873 if field_mode == StructFieldMode::Named {
1874 self.serializer
1875 .field_key(field_item.effective_name())
1876 .map_err(SerializeError::Backend)?;
1877 }
1878 self.push(PathSegment::Field(Cow::Owned(
1879 field_item.effective_name().to_string(),
1880 )));
1881 self.serialize_field_value(&field_item, field_value)?;
1882 self.pop();
1883 }
1884 self.serializer
1885 .end_struct()
1886 .map_err(SerializeError::Backend)?;
1887 Ok(())
1888 }
1889 }
1890 }
1891
1892 fn serialize_standard_externally_tagged<'mem, 'facet>(
1893 &mut self,
1894 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
1895 variant: &'static facet_core::Variant,
1896 ) -> Result<(), SerializeError<S::Error>> {
1897 let field_mode = self.serializer.struct_field_mode();
1898
1899 match variant.data.kind {
1900 StructKind::Unit => {
1901 self.serializer
1902 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
1903 .map_err(SerializeError::Backend)?;
1904 Ok(())
1905 }
1906 StructKind::TupleStruct | StructKind::Tuple => {
1907 self.serializer
1908 .begin_struct()
1909 .map_err(SerializeError::Backend)?;
1910 self.serializer
1911 .field_key(variant.effective_name())
1912 .map_err(SerializeError::Backend)?;
1913
1914 let field_count = variant.data.fields.len();
1915 if field_count == 1 {
1916 let inner = enum_
1917 .field(0)
1918 .map_err(|_| {
1919 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
1920 })?
1921 .ok_or(SerializeError::Internal(Cow::Borrowed(
1922 "variant reported 1 field but field(0) returned None",
1923 )))?;
1924 if let Some(field_def) = variant.data.fields.first().copied()
1925 && let Some(proxy_def) =
1926 field_def.effective_proxy(self.serializer.format_namespace())
1927 {
1928 self.with_field_context(Some(field_def), |this| {
1929 this.serialize_via_proxy(inner, proxy_def)
1930 })?;
1931 } else {
1932 self.with_field_context(variant.data.fields.first().copied(), |this| {
1933 this.serialize_impl(inner)
1934 })?;
1935 }
1936 } else {
1937 self.serializer
1938 .begin_seq()
1939 .map_err(SerializeError::Backend)?;
1940 for idx in 0..field_count {
1941 let inner = enum_
1942 .field(idx)
1943 .map_err(|_| {
1944 SerializeError::Internal(Cow::Borrowed(
1945 "variant field lookup failed",
1946 ))
1947 })?
1948 .ok_or(SerializeError::Internal(Cow::Borrowed(
1949 "variant field missing while iterating tuple fields",
1950 )))?;
1951 self.push(PathSegment::Index(idx));
1952 if let Some(field_def) = variant.data.fields.get(idx).copied()
1953 && let Some(proxy_def) =
1954 field_def.effective_proxy(self.serializer.format_namespace())
1955 {
1956 self.with_field_context(Some(field_def), |this| {
1957 this.serialize_via_proxy(inner, proxy_def)
1958 })?;
1959 } else {
1960 self.with_field_context(
1961 variant.data.fields.get(idx).copied(),
1962 |this| this.serialize_impl(inner),
1963 )?;
1964 }
1965 self.pop();
1966 }
1967 self.serializer.end_seq().map_err(SerializeError::Backend)?;
1968 }
1969
1970 self.serializer
1971 .end_struct()
1972 .map_err(SerializeError::Backend)?;
1973 Ok(())
1974 }
1975 StructKind::Struct => {
1976 self.serializer
1977 .begin_struct()
1978 .map_err(SerializeError::Backend)?;
1979 self.serializer
1980 .field_key(variant.effective_name())
1981 .map_err(SerializeError::Backend)?;
1982
1983 self.serializer
1984 .begin_struct()
1985 .map_err(SerializeError::Backend)?;
1986 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
1987 enum_.fields_for_binary_serialize().collect()
1988 } else {
1989 enum_.fields_for_serialize().collect()
1990 };
1991 sort_fields_if_needed(self.serializer, &mut fields);
1992 for (field_item, field_value) in fields {
1993 self.serializer
1994 .field_metadata(&field_item)
1995 .map_err(SerializeError::Backend)?;
1996 if field_mode == StructFieldMode::Named {
1997 self.serializer
1998 .field_key(field_item.effective_name())
1999 .map_err(SerializeError::Backend)?;
2000 }
2001 self.push(PathSegment::Field(Cow::Owned(
2002 field_item.effective_name().to_string(),
2003 )));
2004 self.serialize_field_value(&field_item, field_value)?;
2005 self.pop();
2006 }
2007 self.serializer
2008 .end_struct()
2009 .map_err(SerializeError::Backend)?;
2010
2011 self.serializer
2012 .end_struct()
2013 .map_err(SerializeError::Backend)?;
2014 Ok(())
2015 }
2016 }
2017 }
2018
2019 fn serialize_untagged_enum<'mem, 'facet>(
2020 &mut self,
2021 enum_: facet_reflect::PeekEnum<'mem, 'facet>,
2022 variant: &'static facet_core::Variant,
2023 ) -> Result<(), SerializeError<S::Error>> {
2024 let field_mode = self.serializer.struct_field_mode();
2025
2026 match variant.data.kind {
2027 StructKind::Unit => self
2028 .serializer
2029 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
2030 .map_err(SerializeError::Backend),
2031 StructKind::TupleStruct | StructKind::Tuple => {
2032 let field_count = variant.data.fields.len();
2033 if field_count == 1 {
2034 let inner = enum_
2035 .field(0)
2036 .map_err(|_| {
2037 SerializeError::Internal(Cow::Borrowed("variant field lookup failed"))
2038 })?
2039 .ok_or(SerializeError::Internal(Cow::Borrowed(
2040 "variant reported 1 field but field(0) returned None",
2041 )))?;
2042 let field_def = variant.data.fields.first().copied();
2043 self.with_field_context(field_def, |this| this.serialize_impl(inner))
2044 } else {
2045 self.serializer
2046 .begin_seq()
2047 .map_err(SerializeError::Backend)?;
2048 for idx in 0..field_count {
2049 let inner = enum_
2050 .field(idx)
2051 .map_err(|_| {
2052 SerializeError::Internal(Cow::Borrowed(
2053 "variant field lookup failed",
2054 ))
2055 })?
2056 .ok_or(SerializeError::Internal(Cow::Borrowed(
2057 "variant field missing while iterating tuple fields",
2058 )))?;
2059 self.push(PathSegment::Index(idx));
2060 let field_def = variant.data.fields.get(idx).copied();
2061 self.with_field_context(field_def, |this| this.serialize_impl(inner))?;
2062 self.pop();
2063 }
2064 self.serializer.end_seq().map_err(SerializeError::Backend)?;
2065 Ok(())
2066 }
2067 }
2068 StructKind::Struct => {
2069 self.serializer
2070 .begin_struct()
2071 .map_err(SerializeError::Backend)?;
2072 let mut fields: alloc::vec::Vec<_> = if field_mode == StructFieldMode::Unnamed {
2073 enum_.fields_for_binary_serialize().collect()
2074 } else {
2075 enum_.fields_for_serialize().collect()
2076 };
2077 sort_fields_if_needed(self.serializer, &mut fields);
2078 for (field_item, field_value) in fields {
2079 self.serializer
2080 .field_metadata(&field_item)
2081 .map_err(SerializeError::Backend)?;
2082 if field_mode == StructFieldMode::Named {
2083 self.serializer
2084 .field_key(field_item.effective_name())
2085 .map_err(SerializeError::Backend)?;
2086 }
2087 self.push(PathSegment::Field(Cow::Owned(
2088 field_item.effective_name().to_string(),
2089 )));
2090 self.serialize_field_value(&field_item, field_value)?;
2091 self.pop();
2092 }
2093 self.serializer
2094 .end_struct()
2095 .map_err(SerializeError::Backend)?;
2096 Ok(())
2097 }
2098 }
2099 }
2100
2101 fn serialize_dynamic_value<'mem, 'facet>(
2102 &mut self,
2103 dynamic: facet_reflect::PeekDynamicValue<'mem, 'facet>,
2104 ) -> Result<(), SerializeError<S::Error>> {
2105 let tagged = self.serializer.dynamic_value_encoding() == DynamicValueEncoding::Tagged;
2106
2107 match dynamic.kind() {
2108 DynValueKind::Null => {
2109 if tagged {
2110 self.serializer
2111 .dynamic_value_tag(DynamicValueTag::Null)
2112 .map_err(SerializeError::Backend)?;
2113 }
2114 self.serializer
2115 .scalar(ScalarValue::Null)
2116 .map_err(SerializeError::Backend)
2117 }
2118 DynValueKind::Bool => {
2119 let value = dynamic.as_bool().ok_or_else(|| {
2120 SerializeError::Internal(Cow::Borrowed("dynamic bool missing value"))
2121 })?;
2122 if tagged {
2123 self.serializer
2124 .dynamic_value_tag(DynamicValueTag::Bool)
2125 .map_err(SerializeError::Backend)?;
2126 }
2127 self.serializer
2128 .scalar(ScalarValue::Bool(value))
2129 .map_err(SerializeError::Backend)
2130 }
2131 DynValueKind::Number => {
2132 if let Some(n) = dynamic.as_i64() {
2133 if tagged {
2134 self.serializer
2135 .dynamic_value_tag(DynamicValueTag::I64)
2136 .map_err(SerializeError::Backend)?;
2137 }
2138 self.serializer
2139 .scalar(ScalarValue::I64(n))
2140 .map_err(SerializeError::Backend)
2141 } else if let Some(n) = dynamic.as_u64() {
2142 if tagged {
2143 self.serializer
2144 .dynamic_value_tag(DynamicValueTag::U64)
2145 .map_err(SerializeError::Backend)?;
2146 }
2147 self.serializer
2148 .scalar(ScalarValue::U64(n))
2149 .map_err(SerializeError::Backend)
2150 } else if let Some(n) = dynamic.as_f64() {
2151 if tagged {
2152 self.serializer
2153 .dynamic_value_tag(DynamicValueTag::F64)
2154 .map_err(SerializeError::Backend)?;
2155 }
2156 self.serializer
2157 .scalar(ScalarValue::F64(n))
2158 .map_err(SerializeError::Backend)
2159 } else {
2160 Err(SerializeError::Unsupported(Cow::Borrowed(
2161 "dynamic number not representable",
2162 )))
2163 }
2164 }
2165 DynValueKind::String => {
2166 let value = dynamic.as_str().ok_or_else(|| {
2167 SerializeError::Internal(Cow::Borrowed("dynamic string missing value"))
2168 })?;
2169 if tagged {
2170 self.serializer
2171 .dynamic_value_tag(DynamicValueTag::String)
2172 .map_err(SerializeError::Backend)?;
2173 }
2174 self.serializer
2175 .scalar(ScalarValue::Str(Cow::Borrowed(value)))
2176 .map_err(SerializeError::Backend)
2177 }
2178 DynValueKind::Bytes => {
2179 let value = dynamic.as_bytes().ok_or_else(|| {
2180 SerializeError::Internal(Cow::Borrowed("dynamic bytes missing value"))
2181 })?;
2182 if tagged {
2183 self.serializer
2184 .dynamic_value_tag(DynamicValueTag::Bytes)
2185 .map_err(SerializeError::Backend)?;
2186 }
2187 self.serializer
2188 .scalar(ScalarValue::Bytes(Cow::Borrowed(value)))
2189 .map_err(SerializeError::Backend)
2190 }
2191 DynValueKind::Array => {
2192 let len = dynamic.array_len().ok_or_else(|| {
2193 SerializeError::Internal(Cow::Borrowed("dynamic array missing length"))
2194 })?;
2195 if tagged {
2196 self.serializer
2197 .dynamic_value_tag(DynamicValueTag::Array)
2198 .map_err(SerializeError::Backend)?;
2199 }
2200 self.serializer
2201 .begin_seq_with_len(len)
2202 .map_err(SerializeError::Backend)?;
2203 if let Some(iter) = dynamic.array_iter() {
2204 for (idx, item) in iter.enumerate() {
2205 self.push(PathSegment::Index(idx));
2206 self.serialize_impl(item)?;
2207 self.pop();
2208 }
2209 }
2210 self.serializer.end_seq().map_err(SerializeError::Backend)
2211 }
2212 DynValueKind::Object => {
2213 let len = dynamic.object_len().ok_or_else(|| {
2214 SerializeError::Internal(Cow::Borrowed("dynamic object missing length"))
2215 })?;
2216 if tagged {
2217 self.serializer
2218 .dynamic_value_tag(DynamicValueTag::Object)
2219 .map_err(SerializeError::Backend)?;
2220 }
2221 match self.serializer.map_encoding() {
2222 MapEncoding::Pairs => {
2223 self.serializer
2224 .begin_map_with_len(len)
2225 .map_err(SerializeError::Backend)?;
2226 if let Some(iter) = dynamic.object_iter() {
2227 for (key, value) in iter {
2228 self.serializer
2229 .scalar(ScalarValue::Str(Cow::Borrowed(key)))
2230 .map_err(SerializeError::Backend)?;
2231 self.push(PathSegment::Field(Cow::Owned(key.to_string())));
2232 self.serialize_impl(value)?;
2233 self.pop();
2234 }
2235 }
2236 self.serializer.end_map().map_err(SerializeError::Backend)
2237 }
2238 MapEncoding::Struct => {
2239 self.serializer
2240 .begin_struct()
2241 .map_err(SerializeError::Backend)?;
2242 if let Some(iter) = dynamic.object_iter() {
2243 for (key, value) in iter {
2244 self.serializer
2245 .field_key(key)
2246 .map_err(SerializeError::Backend)?;
2247 self.push(PathSegment::Field(Cow::Owned(key.to_string())));
2248 self.serialize_impl(value)?;
2249 self.pop();
2250 }
2251 }
2252 self.serializer
2253 .end_struct()
2254 .map_err(SerializeError::Backend)
2255 }
2256 }
2257 }
2258 DynValueKind::DateTime => {
2259 let dt = dynamic.as_datetime().ok_or_else(|| {
2260 SerializeError::Internal(Cow::Borrowed("dynamic datetime missing value"))
2261 })?;
2262 if tagged {
2263 self.serializer
2264 .dynamic_value_tag(DynamicValueTag::DateTime)
2265 .map_err(SerializeError::Backend)?;
2266 }
2267 let s = format_dyn_datetime(dt);
2268 self.serializer
2269 .scalar(ScalarValue::Str(Cow::Owned(s)))
2270 .map_err(SerializeError::Backend)
2271 }
2272 DynValueKind::QName | DynValueKind::Uuid => Err(SerializeError::Unsupported(
2273 Cow::Borrowed("dynamic QName/Uuid serialization is not supported"),
2274 )),
2275 _ => Err(SerializeError::Internal(Cow::Borrowed(
2277 "unsupported dynamic value kind",
2278 ))),
2279 }
2280 }
2281
2282 #[allow(unsafe_code)]
2283 fn serialize_via_proxy<'mem, 'facet>(
2284 &mut self,
2285 value: Peek<'mem, 'facet>,
2286 proxy_def: &'static facet_core::ProxyDef,
2287 ) -> Result<(), SerializeError<S::Error>> {
2288 let proxy_shape = proxy_def.shape;
2289 let proxy_layout = proxy_shape.layout.sized_layout().map_err(|_| {
2290 SerializeError::Unsupported(Cow::Borrowed("proxy type must be sized for serialization"))
2291 })?;
2292
2293 let proxy_uninit = facet_core::alloc_for_layout(proxy_layout);
2294 let convert_result = unsafe { (proxy_def.convert_out)(value.data(), proxy_uninit) };
2295
2296 let proxy_ptr = match convert_result {
2297 Ok(ptr) => ptr,
2298 Err(msg) => {
2299 unsafe { facet_core::dealloc_for_layout(proxy_uninit.assume_init(), proxy_layout) };
2300 return Err(SerializeError::Unsupported(Cow::Owned(msg)));
2301 }
2302 };
2303
2304 let proxy_peek = unsafe { Peek::unchecked_new(proxy_ptr.as_const(), proxy_shape) };
2305 let result = self.serialize_impl(proxy_peek);
2306
2307 unsafe {
2308 let _ = proxy_shape.call_drop_in_place(proxy_ptr);
2309 facet_core::dealloc_for_layout(proxy_ptr, proxy_layout);
2310 }
2311
2312 result
2313 }
2314}
2315
2316impl<E: Debug> std::error::Error for SerializeError<E> {}
2317
2318fn def_kind_name(def: &Def) -> &'static str {
2320 match def {
2321 Def::Undefined => "Undefined",
2322 Def::Scalar => "Scalar",
2323 Def::Map(_) => "Map",
2324 Def::Set(_) => "Set",
2325 Def::List(_) => "List",
2326 Def::Array(_) => "Array",
2327 Def::NdArray(_) => "NdArray",
2328 Def::Slice(_) => "Slice",
2329 Def::Option(_) => "Option",
2330 Def::Result(_) => "Result",
2331 Def::DynamicValue(_) => "DynamicValue",
2332 Def::Pointer(_) => "Pointer",
2333 _ => "Unknown",
2334 }
2335}
2336
2337pub fn serialize_root<'mem, 'facet, S>(
2339 serializer: &mut S,
2340 value: Peek<'mem, 'facet>,
2341) -> Result<(), SerializeError<S::Error>>
2342where
2343 S: FormatSerializer,
2344{
2345 let mut ctx = SerializeContext::new(serializer);
2346 ctx.serialize(value)
2347}
2348
2349fn sort_fields_if_needed<'mem, 'facet, S>(
2351 _serializer: &S,
2352 _fields: &mut alloc::vec::Vec<(facet_reflect::FieldItem, Peek<'mem, 'facet>)>,
2353) where
2354 S: FormatSerializer,
2355{
2356 }
2358
2359fn format_dyn_datetime(
2360 (year, month, day, hour, minute, second, nanos, kind): (
2361 i32,
2362 u8,
2363 u8,
2364 u8,
2365 u8,
2366 u8,
2367 u32,
2368 DynDateTimeKind,
2369 ),
2370) -> String {
2371 let mut out = String::new();
2372 match kind {
2373 DynDateTimeKind::Offset { offset_minutes } => {
2374 let _ = write!(
2375 out,
2376 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}",
2377 year, month, day, hour, minute, second
2378 );
2379 if nanos > 0 {
2380 let _ = write!(out, ".{:09}", nanos);
2381 }
2382 if offset_minutes == 0 {
2383 out.push('Z');
2384 } else {
2385 let sign = if offset_minutes >= 0 { '+' } else { '-' };
2386 let abs = offset_minutes.unsigned_abs();
2387 let _ = write!(out, "{}{:02}:{:02}", sign, abs / 60, abs % 60);
2388 }
2389 }
2390 DynDateTimeKind::LocalDateTime => {
2391 let _ = write!(
2392 out,
2393 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}",
2394 year, month, day, hour, minute, second
2395 );
2396 if nanos > 0 {
2397 let _ = write!(out, ".{:09}", nanos);
2398 }
2399 }
2400 DynDateTimeKind::LocalDate => {
2401 let _ = write!(out, "{:04}-{:02}-{:02}", year, month, day);
2402 }
2403 DynDateTimeKind::LocalTime => {
2404 let _ = write!(out, "{:02}:{:02}:{:02}", hour, minute, second);
2405 if nanos > 0 {
2406 let _ = write!(out, ".{:09}", nanos);
2407 }
2408 }
2409 _ => {
2412 let _ = write!(
2413 out,
2414 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}",
2415 year, month, day, hour, minute, second
2416 );
2417 if nanos > 0 {
2418 let _ = write!(out, ".{:09}", nanos);
2419 }
2420 }
2421 }
2422 out
2423}
2424
2425fn serialize_numeric_enum<S>(
2426 serializer: &mut S,
2427 variant: &'static facet_core::Variant,
2428) -> Result<(), SerializeError<S::Error>>
2429where
2430 S: FormatSerializer,
2431{
2432 let discriminant = variant
2433 .discriminant
2434 .ok_or(SerializeError::Unsupported(Cow::Borrowed(
2435 "Enum without a discriminant",
2436 )))?;
2437 serializer
2438 .scalar(ScalarValue::I64(discriminant))
2439 .map_err(SerializeError::Backend)
2440}
2441
2442fn deref_if_pointer<'mem, 'facet>(peek: Peek<'mem, 'facet>) -> Peek<'mem, 'facet> {
2444 if let Ok(ptr) = peek.into_pointer()
2445 && let Some(target) = ptr.borrow_inner()
2446 {
2447 return deref_if_pointer(target);
2448 }
2449 peek
2450}
2451
2452pub fn serialize_value_with_shape<S>(
2478 serializer: &mut S,
2479 value: Peek<'_, '_>,
2480 target_shape: &'static Shape,
2481) -> Result<(), SerializeError<S::Error>>
2482where
2483 S: FormatSerializer,
2484{
2485 let dynamic = value.into_dynamic_value().map_err(|_| {
2486 SerializeError::Unsupported(Cow::Borrowed(
2487 "serialize_value_with_shape requires a DynamicValue type",
2488 ))
2489 })?;
2490
2491 serialize_dynamic_with_shape(serializer, dynamic, target_shape, value.shape())
2492}
2493
2494fn serialize_dynamic_with_shape<S>(
2495 serializer: &mut S,
2496 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2497 target_shape: &'static Shape,
2498 value_shape: &'static Shape,
2499) -> Result<(), SerializeError<S::Error>>
2500where
2501 S: FormatSerializer,
2502{
2503 use facet_core::{ListDef, OptionDef, ScalarType as CoreScalarType, Type, UserType};
2504
2505 if let Def::Pointer(ptr_def) = target_shape.def
2507 && let Some(pointee) = ptr_def.pointee
2508 {
2509 return serialize_dynamic_with_shape(serializer, dynamic, pointee, value_shape);
2510 }
2511
2512 if let Some(inner_shape) = target_shape.inner {
2514 if !matches!(
2516 target_shape.def,
2517 Def::List(_) | Def::Map(_) | Def::Set(_) | Def::Array(_)
2518 ) {
2519 return serialize_dynamic_with_shape(serializer, dynamic, inner_shape, value_shape);
2520 }
2521 }
2522
2523 if let Def::Option(OptionDef { t: inner_shape, .. }) = target_shape.def {
2525 return serialize_option_from_dynamic(serializer, dynamic, inner_shape, value_shape);
2526 }
2527
2528 if let Def::List(ListDef { t: item_shape, .. }) = target_shape.def {
2530 return serialize_list_from_dynamic(serializer, dynamic, item_shape, value_shape);
2531 }
2532
2533 if let Def::Array(array_def) = target_shape.def {
2535 return serialize_array_from_dynamic(serializer, dynamic, array_def.t, value_shape);
2536 }
2537
2538 if let Def::Map(map_def) = target_shape.def {
2540 return serialize_map_from_dynamic(serializer, dynamic, map_def.k, map_def.v, value_shape);
2541 }
2542
2543 if let Some(scalar_type) = CoreScalarType::try_from_shape(target_shape) {
2545 return serialize_scalar_from_dynamic(serializer, dynamic, scalar_type);
2546 }
2547
2548 match target_shape.ty {
2550 Type::User(UserType::Struct(struct_def)) => {
2551 serialize_struct_from_dynamic(serializer, dynamic, struct_def, value_shape)
2552 }
2553 Type::User(UserType::Enum(enum_def)) => {
2554 serialize_enum_from_dynamic(serializer, dynamic, enum_def, target_shape, value_shape)
2555 }
2556 _ => Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2557 "unsupported target shape for serialize_value_with_shape: {}",
2558 target_shape
2559 )))),
2560 }
2561}
2562
2563fn serialize_option_from_dynamic<S>(
2564 serializer: &mut S,
2565 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2566 inner_shape: &'static Shape,
2567 value_shape: &'static Shape,
2568) -> Result<(), SerializeError<S::Error>>
2569where
2570 S: FormatSerializer,
2571{
2572 if dynamic.kind() == DynValueKind::Null {
2573 serializer.serialize_none().map_err(SerializeError::Backend)
2574 } else {
2575 serializer
2576 .begin_option_some()
2577 .map_err(SerializeError::Backend)?;
2578 serialize_dynamic_with_shape(serializer, dynamic, inner_shape, value_shape)
2579 }
2580}
2581
2582fn serialize_list_from_dynamic<S>(
2583 serializer: &mut S,
2584 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2585 item_shape: &'static Shape,
2586 value_shape: &'static Shape,
2587) -> Result<(), SerializeError<S::Error>>
2588where
2589 S: FormatSerializer,
2590{
2591 let len = dynamic.array_len().ok_or_else(|| {
2592 SerializeError::Unsupported(Cow::Borrowed(
2593 "expected array value for list/vec target shape",
2594 ))
2595 })?;
2596
2597 serializer
2598 .begin_seq_with_len(len)
2599 .map_err(SerializeError::Backend)?;
2600
2601 if let Some(iter) = dynamic.array_iter() {
2602 for elem in iter {
2603 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2604 SerializeError::Internal(Cow::Borrowed("array element is not a dynamic value"))
2605 })?;
2606 serialize_dynamic_with_shape(serializer, elem_dyn, item_shape, value_shape)?;
2607 }
2608 }
2609
2610 serializer.end_seq().map_err(SerializeError::Backend)
2611}
2612
2613fn serialize_array_from_dynamic<S>(
2614 serializer: &mut S,
2615 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2616 item_shape: &'static Shape,
2617 value_shape: &'static Shape,
2618) -> Result<(), SerializeError<S::Error>>
2619where
2620 S: FormatSerializer,
2621{
2622 serializer.begin_seq().map_err(SerializeError::Backend)?;
2624
2625 if let Some(iter) = dynamic.array_iter() {
2626 for elem in iter {
2627 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2628 SerializeError::Internal(Cow::Borrowed("array element is not a dynamic value"))
2629 })?;
2630 serialize_dynamic_with_shape(serializer, elem_dyn, item_shape, value_shape)?;
2631 }
2632 }
2633
2634 serializer.end_seq().map_err(SerializeError::Backend)
2635}
2636
2637fn serialize_map_from_dynamic<S>(
2638 serializer: &mut S,
2639 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2640 key_shape: &'static Shape,
2641 value_shape_inner: &'static Shape,
2642 value_shape: &'static Shape,
2643) -> Result<(), SerializeError<S::Error>>
2644where
2645 S: FormatSerializer,
2646{
2647 let len = dynamic.object_len().ok_or_else(|| {
2648 SerializeError::Unsupported(Cow::Borrowed("expected object value for map target shape"))
2649 })?;
2650
2651 match serializer.map_encoding() {
2652 MapEncoding::Pairs => {
2653 serializer
2654 .begin_map_with_len(len)
2655 .map_err(SerializeError::Backend)?;
2656
2657 if let Some(iter) = dynamic.object_iter() {
2658 for (key, val) in iter {
2659 serialize_string_as_scalar(serializer, key, key_shape)?;
2661 let val_dyn = val.into_dynamic_value().map_err(|_| {
2663 SerializeError::Internal(Cow::Borrowed(
2664 "object value is not a dynamic value",
2665 ))
2666 })?;
2667 serialize_dynamic_with_shape(
2668 serializer,
2669 val_dyn,
2670 value_shape_inner,
2671 value_shape,
2672 )?;
2673 }
2674 }
2675
2676 serializer.end_map().map_err(SerializeError::Backend)
2677 }
2678 MapEncoding::Struct => {
2679 serializer.begin_struct().map_err(SerializeError::Backend)?;
2680
2681 if let Some(iter) = dynamic.object_iter() {
2682 for (key, val) in iter {
2683 serializer.field_key(key).map_err(SerializeError::Backend)?;
2684 let val_dyn = val.into_dynamic_value().map_err(|_| {
2685 SerializeError::Internal(Cow::Borrowed(
2686 "object value is not a dynamic value",
2687 ))
2688 })?;
2689 serialize_dynamic_with_shape(
2690 serializer,
2691 val_dyn,
2692 value_shape_inner,
2693 value_shape,
2694 )?;
2695 }
2696 }
2697
2698 serializer.end_struct().map_err(SerializeError::Backend)
2699 }
2700 }
2701}
2702
2703fn serialize_string_as_scalar<S>(
2704 serializer: &mut S,
2705 s: &str,
2706 _key_shape: &'static Shape,
2707) -> Result<(), SerializeError<S::Error>>
2708where
2709 S: FormatSerializer,
2710{
2711 serializer
2714 .scalar(ScalarValue::Str(Cow::Borrowed(s)))
2715 .map_err(SerializeError::Backend)
2716}
2717
2718fn serialize_scalar_from_dynamic<S>(
2719 serializer: &mut S,
2720 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2721 scalar_type: facet_core::ScalarType,
2722) -> Result<(), SerializeError<S::Error>>
2723where
2724 S: FormatSerializer,
2725{
2726 use facet_core::ScalarType as ST;
2727
2728 match scalar_type {
2729 ST::Unit => serializer
2730 .scalar(ScalarValue::Null)
2731 .map_err(SerializeError::Backend),
2732 ST::Bool => {
2733 let v = dynamic
2734 .as_bool()
2735 .ok_or_else(|| SerializeError::Unsupported(Cow::Borrowed("expected bool value")))?;
2736 serializer
2737 .scalar(ScalarValue::Bool(v))
2738 .map_err(SerializeError::Backend)
2739 }
2740 ST::Char => {
2741 let s = dynamic.as_str().ok_or_else(|| {
2742 SerializeError::Unsupported(Cow::Borrowed("expected string value for char"))
2743 })?;
2744 let c = s.chars().next().ok_or_else(|| {
2745 SerializeError::Unsupported(Cow::Borrowed("expected non-empty string for char"))
2746 })?;
2747 serializer
2748 .scalar(ScalarValue::Char(c))
2749 .map_err(SerializeError::Backend)
2750 }
2751 ST::Str | ST::String | ST::CowStr => {
2752 let s = dynamic.as_str().ok_or_else(|| {
2753 SerializeError::Unsupported(Cow::Borrowed("expected string value"))
2754 })?;
2755 serializer
2756 .scalar(ScalarValue::Str(Cow::Borrowed(s)))
2757 .map_err(SerializeError::Backend)
2758 }
2759 ST::U8 | ST::U16 | ST::U32 | ST::U64 | ST::USize => {
2760 let n = dynamic.as_u64().ok_or_else(|| {
2761 SerializeError::Unsupported(Cow::Borrowed("expected unsigned integer value"))
2762 })?;
2763 serializer
2764 .scalar(ScalarValue::U64(n))
2765 .map_err(SerializeError::Backend)
2766 }
2767 ST::U128 => {
2768 let n = dynamic.as_u64().ok_or_else(|| {
2769 SerializeError::Unsupported(Cow::Borrowed("expected unsigned integer value"))
2770 })?;
2771 serializer
2772 .scalar(ScalarValue::U128(n as u128))
2773 .map_err(SerializeError::Backend)
2774 }
2775 ST::I8 | ST::I16 | ST::I32 | ST::I64 | ST::ISize => {
2776 let n = dynamic.as_i64().ok_or_else(|| {
2777 SerializeError::Unsupported(Cow::Borrowed("expected signed integer value"))
2778 })?;
2779 serializer
2780 .scalar(ScalarValue::I64(n))
2781 .map_err(SerializeError::Backend)
2782 }
2783 ST::I128 => {
2784 let n = dynamic.as_i64().ok_or_else(|| {
2785 SerializeError::Unsupported(Cow::Borrowed("expected signed integer value"))
2786 })?;
2787 serializer
2788 .scalar(ScalarValue::I128(n as i128))
2789 .map_err(SerializeError::Backend)
2790 }
2791 ST::F32 | ST::F64 => {
2792 let n = dynamic.as_f64().ok_or_else(|| {
2793 SerializeError::Unsupported(Cow::Borrowed("expected float value"))
2794 })?;
2795 serializer
2796 .scalar(ScalarValue::F64(n))
2797 .map_err(SerializeError::Backend)
2798 }
2799 _ => Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2800 "unsupported scalar type: {:?}",
2801 scalar_type
2802 )))),
2803 }
2804}
2805
2806fn serialize_struct_from_dynamic<S>(
2807 serializer: &mut S,
2808 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2809 struct_def: facet_core::StructType,
2810 value_shape: &'static Shape,
2811) -> Result<(), SerializeError<S::Error>>
2812where
2813 S: FormatSerializer,
2814{
2815 let is_tuple = matches!(struct_def.kind, StructKind::Tuple | StructKind::TupleStruct);
2816
2817 if is_tuple {
2818 serializer.begin_seq().map_err(SerializeError::Backend)?;
2820
2821 let iter = dynamic.array_iter().ok_or_else(|| {
2822 SerializeError::Unsupported(Cow::Borrowed("expected array value for tuple"))
2823 })?;
2824
2825 for (field, elem) in struct_def.fields.iter().zip(iter) {
2826 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2827 SerializeError::Internal(Cow::Borrowed("tuple element is not a dynamic value"))
2828 })?;
2829 serialize_dynamic_with_shape(serializer, elem_dyn, field.shape(), value_shape)?;
2830 }
2831
2832 serializer.end_seq().map_err(SerializeError::Backend)
2833 } else {
2834 let field_mode = serializer.struct_field_mode();
2836
2837 serializer.begin_struct().map_err(SerializeError::Backend)?;
2838
2839 for field in struct_def.fields {
2840 if field.is_metadata() {
2842 continue;
2843 }
2844
2845 let field_name = field.name;
2846 let field_value = dynamic.object_get(field_name).ok_or_else(|| {
2847 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2848 "missing field '{}' in object",
2849 field_name
2850 )))
2851 })?;
2852
2853 if field_mode == StructFieldMode::Named {
2854 serializer
2855 .field_key(field_name)
2856 .map_err(SerializeError::Backend)?;
2857 }
2858
2859 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
2860 SerializeError::Internal(Cow::Borrowed("field value is not a dynamic value"))
2861 })?;
2862 serialize_dynamic_with_shape(serializer, field_dyn, field.shape(), value_shape)?;
2863 }
2864
2865 serializer.end_struct().map_err(SerializeError::Backend)
2866 }
2867}
2868
2869fn serialize_enum_from_dynamic<S>(
2870 serializer: &mut S,
2871 dynamic: facet_reflect::PeekDynamicValue<'_, '_>,
2872 enum_def: facet_core::EnumType,
2873 target_shape: &'static Shape,
2874 value_shape: &'static Shape,
2875) -> Result<(), SerializeError<S::Error>>
2876where
2877 S: FormatSerializer,
2878{
2879 let use_index = serializer.enum_variant_encoding() == EnumVariantEncoding::Index;
2885
2886 match dynamic.kind() {
2887 DynValueKind::String => {
2889 let variant_name = dynamic.as_str().ok_or_else(|| {
2890 SerializeError::Internal(Cow::Borrowed("expected string for unit variant"))
2891 })?;
2892
2893 let (variant_index, variant) = enum_def
2894 .variants
2895 .iter()
2896 .enumerate()
2897 .find(|(_, v)| v.effective_name() == variant_name)
2898 .ok_or_else(|| {
2899 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2900 "unknown variant '{}'",
2901 variant_name
2902 )))
2903 })?;
2904
2905 if use_index {
2906 serializer
2907 .begin_enum_variant(variant_index, variant.effective_name())
2908 .map_err(SerializeError::Backend)?;
2909 Ok(())
2911 } else {
2912 serializer
2913 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
2914 .map_err(SerializeError::Backend)
2915 }
2916 }
2917
2918 DynValueKind::Object => {
2920 let obj_len = dynamic.object_len().unwrap_or(0);
2922 if obj_len != 1 {
2923 return Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
2924 "expected single-key object for enum variant, got {} keys",
2925 obj_len
2926 ))));
2927 }
2928
2929 let (variant_name, payload) = dynamic.object_get_entry(0).ok_or_else(|| {
2930 SerializeError::Internal(Cow::Borrowed("expected object entry for enum variant"))
2931 })?;
2932
2933 let (variant_index, variant) = enum_def
2934 .variants
2935 .iter()
2936 .enumerate()
2937 .find(|(_, v)| v.effective_name() == variant_name)
2938 .ok_or_else(|| {
2939 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2940 "unknown variant '{}'",
2941 variant_name
2942 )))
2943 })?;
2944
2945 let payload_dyn = payload.into_dynamic_value().map_err(|_| {
2946 SerializeError::Internal(Cow::Borrowed("variant payload is not a dynamic value"))
2947 })?;
2948
2949 if use_index {
2950 serializer
2951 .begin_enum_variant(variant_index, variant.effective_name())
2952 .map_err(SerializeError::Backend)?;
2953
2954 match variant.data.kind {
2956 StructKind::Unit => {
2957 }
2959 StructKind::TupleStruct | StructKind::Tuple => {
2960 if variant.data.fields.len() == 1 {
2961 serialize_dynamic_with_shape(
2963 serializer,
2964 payload_dyn,
2965 variant.data.fields[0].shape(),
2966 value_shape,
2967 )?;
2968 } else {
2969 let iter = payload_dyn.array_iter().ok_or_else(|| {
2971 SerializeError::Unsupported(Cow::Borrowed(
2972 "expected array for tuple variant payload",
2973 ))
2974 })?;
2975
2976 for (field, elem) in variant.data.fields.iter().zip(iter) {
2977 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
2978 SerializeError::Internal(Cow::Borrowed(
2979 "tuple element is not a dynamic value",
2980 ))
2981 })?;
2982 serialize_dynamic_with_shape(
2983 serializer,
2984 elem_dyn,
2985 field.shape(),
2986 value_shape,
2987 )?;
2988 }
2989 }
2990 }
2991 StructKind::Struct => {
2992 for field in variant.data.fields {
2994 let field_value =
2995 payload_dyn.object_get(field.name).ok_or_else(|| {
2996 SerializeError::Unsupported(Cow::Owned(alloc::format!(
2997 "missing field '{}' in struct variant",
2998 field.name
2999 )))
3000 })?;
3001 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
3002 SerializeError::Internal(Cow::Borrowed(
3003 "field value is not a dynamic value",
3004 ))
3005 })?;
3006 serialize_dynamic_with_shape(
3007 serializer,
3008 field_dyn,
3009 field.shape(),
3010 value_shape,
3011 )?;
3012 }
3013 }
3014 }
3015
3016 Ok(())
3017 } else {
3018 serializer.begin_struct().map_err(SerializeError::Backend)?;
3020 serializer
3021 .field_key(variant.effective_name())
3022 .map_err(SerializeError::Backend)?;
3023
3024 match variant.data.kind {
3025 StructKind::Unit => {
3026 serializer
3027 .scalar(ScalarValue::Null)
3028 .map_err(SerializeError::Backend)?;
3029 }
3030 StructKind::TupleStruct | StructKind::Tuple => {
3031 if variant.data.fields.len() == 1 {
3032 serialize_dynamic_with_shape(
3033 serializer,
3034 payload_dyn,
3035 variant.data.fields[0].shape(),
3036 value_shape,
3037 )?;
3038 } else {
3039 serializer.begin_seq().map_err(SerializeError::Backend)?;
3040 let iter = payload_dyn.array_iter().ok_or_else(|| {
3041 SerializeError::Unsupported(Cow::Borrowed(
3042 "expected array for tuple variant",
3043 ))
3044 })?;
3045 for (field, elem) in variant.data.fields.iter().zip(iter) {
3046 let elem_dyn = elem.into_dynamic_value().map_err(|_| {
3047 SerializeError::Internal(Cow::Borrowed(
3048 "element is not a dynamic value",
3049 ))
3050 })?;
3051 serialize_dynamic_with_shape(
3052 serializer,
3053 elem_dyn,
3054 field.shape(),
3055 value_shape,
3056 )?;
3057 }
3058 serializer.end_seq().map_err(SerializeError::Backend)?;
3059 }
3060 }
3061 StructKind::Struct => {
3062 serializer.begin_struct().map_err(SerializeError::Backend)?;
3063 for field in variant.data.fields {
3064 let field_value =
3065 payload_dyn.object_get(field.name).ok_or_else(|| {
3066 SerializeError::Unsupported(Cow::Owned(alloc::format!(
3067 "missing field '{}'",
3068 field.name
3069 )))
3070 })?;
3071 serializer
3072 .field_key(field.name)
3073 .map_err(SerializeError::Backend)?;
3074 let field_dyn = field_value.into_dynamic_value().map_err(|_| {
3075 SerializeError::Internal(Cow::Borrowed(
3076 "field is not a dynamic value",
3077 ))
3078 })?;
3079 serialize_dynamic_with_shape(
3080 serializer,
3081 field_dyn,
3082 field.shape(),
3083 value_shape,
3084 )?;
3085 }
3086 serializer.end_struct().map_err(SerializeError::Backend)?;
3087 }
3088 }
3089
3090 serializer.end_struct().map_err(SerializeError::Backend)
3091 }
3092 }
3093
3094 DynValueKind::Null => {
3096 if let Some((variant_index, variant)) = enum_def
3099 .variants
3100 .iter()
3101 .enumerate()
3102 .find(|(_, v)| v.name.eq_ignore_ascii_case("null") || v.name == "None")
3103 {
3104 if use_index {
3105 serializer
3106 .begin_enum_variant(variant_index, variant.effective_name())
3107 .map_err(SerializeError::Backend)?;
3108 Ok(())
3109 } else {
3110 serializer
3111 .scalar(ScalarValue::Str(Cow::Borrowed(variant.effective_name())))
3112 .map_err(SerializeError::Backend)
3113 }
3114 } else {
3115 Err(SerializeError::Unsupported(Cow::Borrowed(
3116 "null value for enum without null/None variant",
3117 )))
3118 }
3119 }
3120
3121 _ => {
3122 let _ = target_shape; Err(SerializeError::Unsupported(Cow::Owned(alloc::format!(
3126 "unsupported dynamic value kind {:?} for enum serialization",
3127 dynamic.kind()
3128 ))))
3129 }
3130 }
3131}