1extern crate alloc;
12
13use alloc::borrow::Cow;
14use alloc::vec::Vec;
15use core::marker::PhantomData;
16
17use facet_core::{Def, ScalarType, Shape};
18use facet_format::{
19 DynamicValueEncoding, DynamicValueTag, EnumVariantEncoding, FormatSerializer, MapEncoding,
20 SerializeError as FormatSerializeError, StructFieldMode, serialize_root,
21 serialize_value_with_shape,
22};
23use facet_reflect::Peek;
24
25use crate::error::SerializeError;
26
27pub trait Writer {
77 fn write_byte(&mut self, byte: u8) -> Result<(), SerializeError>;
79
80 fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError>;
82}
83
84impl Writer for Vec<u8> {
85 fn write_byte(&mut self, byte: u8) -> Result<(), SerializeError> {
86 self.push(byte);
87 Ok(())
88 }
89
90 fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError> {
91 self.extend_from_slice(bytes);
92 Ok(())
93 }
94}
95
96#[derive(Debug, Clone, PartialEq, Eq)]
98pub enum Segment<'a> {
99 Staged { offset: usize, len: usize },
101 Reference { bytes: &'a [u8] },
103}
104
105#[derive(Debug, Clone)]
107pub struct ScatterPlan<'a> {
108 staging: Vec<u8>,
109 segments: Vec<Segment<'a>>,
110 total_size: usize,
111}
112
113impl<'a> ScatterPlan<'a> {
114 pub const fn total_size(&self) -> usize {
116 self.total_size
117 }
118
119 pub fn staging(&self) -> &[u8] {
121 &self.staging
122 }
123
124 pub fn segments(&self) -> &[Segment<'a>] {
126 &self.segments
127 }
128
129 pub fn write_into(&self, dest: &mut [u8]) -> Result<(), SerializeError> {
133 if dest.len() != self.total_size {
134 return Err(SerializeError::Custom(alloc::format!(
135 "destination length mismatch: expected {}, got {}",
136 self.total_size,
137 dest.len()
138 )));
139 }
140
141 let mut cursor = 0usize;
142 for segment in &self.segments {
143 match segment {
144 Segment::Staged { offset, len } => {
145 let src = &self.staging[*offset..*offset + *len];
146 dest[cursor..cursor + *len].copy_from_slice(src);
147 cursor += *len;
148 }
149 Segment::Reference { bytes } => {
150 dest[cursor..cursor + bytes.len()].copy_from_slice(bytes);
151 cursor += bytes.len();
152 }
153 }
154 }
155
156 debug_assert_eq!(cursor, self.total_size);
157 Ok(())
158 }
159}
160
161struct ScatterBuilder<'a> {
162 staging: Vec<u8>,
163 segments: Vec<Segment<'a>>,
164 total_size: usize,
165}
166
167impl<'a> ScatterBuilder<'a> {
168 const fn new() -> Self {
169 Self {
170 staging: Vec::new(),
171 segments: Vec::new(),
172 total_size: 0,
173 }
174 }
175
176 fn finish(self) -> ScatterPlan<'a> {
177 ScatterPlan {
178 staging: self.staging,
179 segments: self.segments,
180 total_size: self.total_size,
181 }
182 }
183
184 fn push_staged_segment(&mut self, offset: usize, len: usize) {
185 if len == 0 {
186 return;
187 }
188
189 if let Some(Segment::Staged {
190 offset: prev_offset,
191 len: prev_len,
192 }) = self.segments.last_mut()
193 && *prev_offset + *prev_len == offset
194 {
195 *prev_len += len;
196 return;
197 }
198
199 self.segments.push(Segment::Staged { offset, len });
200 }
201
202 fn push_reference_segment(&mut self, bytes: &[u8]) {
203 if bytes.is_empty() {
204 return;
205 }
206
207 #[allow(unsafe_code)]
211 let bytes: &'a [u8] = unsafe { core::mem::transmute(bytes) };
212 self.total_size += bytes.len();
213 self.segments.push(Segment::Reference { bytes });
214 }
215}
216
217impl Writer for ScatterBuilder<'_> {
218 fn write_byte(&mut self, byte: u8) -> Result<(), SerializeError> {
219 let offset = self.staging.len();
220 self.staging.push(byte);
221 self.total_size += 1;
222 self.push_staged_segment(offset, 1);
223 Ok(())
224 }
225
226 fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError> {
227 if bytes.is_empty() {
228 return Ok(());
229 }
230 let offset = self.staging.len();
231 self.staging.extend_from_slice(bytes);
232 self.total_size += bytes.len();
233 self.push_staged_segment(offset, bytes.len());
234 Ok(())
235 }
236}
237
238struct CopyWriter<'a, W: Writer + ?Sized> {
239 inner: &'a mut W,
240}
241
242impl<'a, W: Writer + ?Sized> CopyWriter<'a, W> {
243 const fn new(inner: &'a mut W) -> Self {
244 Self { inner }
245 }
246}
247
248impl<W: Writer + ?Sized> Writer for CopyWriter<'_, W> {
249 fn write_byte(&mut self, byte: u8) -> Result<(), SerializeError> {
250 self.inner.write_byte(byte)
251 }
252
253 fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError> {
254 self.inner.write_bytes(bytes)
255 }
256}
257
258trait PostcardWriter<'a>: Writer {
259 fn write_referenced_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError>;
260}
261
262impl<'a, W: Writer + ?Sized> PostcardWriter<'a> for CopyWriter<'_, W> {
263 fn write_referenced_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError> {
264 self.inner.write_bytes(bytes)
265 }
266}
267
268impl<'a> PostcardWriter<'a> for ScatterBuilder<'a> {
269 fn write_referenced_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError> {
270 self.push_reference_segment(bytes);
271 Ok(())
272 }
273}
274
275pub fn to_vec<'facet, T>(value: &T) -> Result<Vec<u8>, SerializeError>
292where
293 T: facet_core::Facet<'facet>,
294{
295 let mut buffer = Vec::new();
296 to_writer_fallible(value, &mut buffer)?;
297 Ok(buffer)
298}
299
300pub fn to_writer_fallible<'facet, T, W>(value: &T, writer: &mut W) -> Result<(), SerializeError>
339where
340 T: facet_core::Facet<'facet>,
341 W: Writer,
342{
343 let peek = Peek::new(value);
344 let mut serializer = PostcardSerializer::new(CopyWriter::new(writer));
345 serialize_root(&mut serializer, peek).map_err(map_format_error)
346}
347
348pub fn peek_to_vec(peek: Peek<'_, '_>) -> Result<Vec<u8>, SerializeError> {
370 let mut buffer = Vec::new();
371 let mut serializer = PostcardSerializer::new(CopyWriter::new(&mut buffer));
372 serialize_root(&mut serializer, peek).map_err(map_format_error)?;
373 Ok(buffer)
374}
375
376pub fn to_scatter_plan<'a, T>(value: &'a T) -> Result<ScatterPlan<'a>, SerializeError>
381where
382 T: facet_core::Facet<'a> + ?Sized,
383{
384 peek_to_scatter_plan(Peek::new(value))
385}
386
387pub fn peek_to_scatter_plan<'input, 'facet>(
389 peek: Peek<'input, 'facet>,
390) -> Result<ScatterPlan<'input>, SerializeError> {
391 let mut serializer = PostcardSerializer::new(ScatterBuilder::new());
392 serialize_root(&mut serializer, peek).map_err(map_format_error)?;
393 Ok(serializer.into_writer().finish())
394}
395
396pub fn to_vec_with_shape<'facet, T>(
438 value: &T,
439 target_shape: &'static Shape,
440) -> Result<Vec<u8>, SerializeError>
441where
442 T: facet_core::Facet<'facet>,
443{
444 let mut buffer = Vec::new();
445 let peek = Peek::new(value);
446 let mut serializer = PostcardSerializer::new(CopyWriter::new(&mut buffer));
447 serialize_value_with_shape(&mut serializer, peek, target_shape).map_err(map_format_error)?;
448 Ok(buffer)
449}
450
451fn map_format_error(error: FormatSerializeError<SerializeError>) -> SerializeError {
452 match error {
453 FormatSerializeError::Backend(err) => err,
454 FormatSerializeError::Reflect(err) => SerializeError::Custom(alloc::format!("{err}")),
455 FormatSerializeError::Unsupported(message) => SerializeError::Custom(message.into_owned()),
456 FormatSerializeError::Internal(message) => SerializeError::Custom(message.into_owned()),
457 }
458}
459
460fn has_trailing_attr(field: Option<&facet_core::Field>) -> bool {
461 field.is_some_and(|f| f.has_builtin_attr("trailing"))
462}
463
464struct PostcardSerializer<'a, W> {
465 writer: W,
466 _marker: PhantomData<&'a ()>,
467}
468
469impl<'a, W> PostcardSerializer<'a, W> {
470 const fn new(writer: W) -> Self {
471 Self {
472 writer,
473 _marker: PhantomData,
474 }
475 }
476
477 fn into_writer(self) -> W {
478 self.writer
479 }
480
481 fn write_str(&mut self, s: &str) -> Result<(), SerializeError>
482 where
483 W: Writer,
484 {
485 write_varint(s.len() as u64, &mut self.writer)?;
486 self.writer.write_bytes(s.as_bytes())
487 }
488
489 fn write_str_borrowed(&mut self, s: &str) -> Result<(), SerializeError>
490 where
491 W: PostcardWriter<'a>,
492 {
493 write_varint(s.len() as u64, &mut self.writer)?;
494 self.writer.write_referenced_bytes(s.as_bytes())
495 }
496
497 fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError>
498 where
499 W: Writer,
500 {
501 write_varint(bytes.len() as u64, &mut self.writer)?;
502 self.writer.write_bytes(bytes)
503 }
504
505 fn write_bytes_borrowed(&mut self, bytes: &[u8]) -> Result<(), SerializeError>
506 where
507 W: PostcardWriter<'a>,
508 {
509 write_varint(bytes.len() as u64, &mut self.writer)?;
510 self.writer.write_referenced_bytes(bytes)
511 }
512
513 fn write_byte_array_borrowed(&mut self, bytes: &[u8]) -> Result<(), SerializeError>
514 where
515 W: PostcardWriter<'a>,
516 {
517 self.writer.write_referenced_bytes(bytes)
518 }
519
520 fn write_dynamic_tag(&mut self, tag: DynamicValueTag) -> Result<(), SerializeError>
521 where
522 W: Writer,
523 {
524 let byte = match tag {
525 DynamicValueTag::Null => 0,
526 DynamicValueTag::Bool => 1,
527 DynamicValueTag::I64 => 2,
528 DynamicValueTag::U64 => 3,
529 DynamicValueTag::F64 => 4,
530 DynamicValueTag::String => 5,
531 DynamicValueTag::Bytes => 6,
532 DynamicValueTag::Array => 7,
533 DynamicValueTag::Object => 8,
534 DynamicValueTag::DateTime => 9,
535 };
536 self.writer.write_byte(byte)
537 }
538}
539
540impl<'a, W: PostcardWriter<'a>> FormatSerializer for PostcardSerializer<'a, W> {
541 type Error = SerializeError;
542
543 fn begin_struct(&mut self) -> Result<(), Self::Error> {
544 Ok(())
545 }
546
547 fn field_key(&mut self, _key: &str) -> Result<(), Self::Error> {
548 Err(SerializeError::Custom(
549 "postcard does not support named fields".into(),
550 ))
551 }
552
553 fn end_struct(&mut self) -> Result<(), Self::Error> {
554 Ok(())
555 }
556
557 fn begin_seq(&mut self) -> Result<(), Self::Error> {
558 Ok(())
559 }
560
561 fn end_seq(&mut self) -> Result<(), Self::Error> {
562 Ok(())
563 }
564
565 fn scalar(&mut self, scalar: facet_format::ScalarValue<'_>) -> Result<(), Self::Error> {
566 match scalar {
567 facet_format::ScalarValue::Null | facet_format::ScalarValue::Unit => Ok(()),
568 facet_format::ScalarValue::Bool(v) => self.writer.write_byte(if v { 1 } else { 0 }),
569 facet_format::ScalarValue::Char(c) => {
570 let mut buf = [0u8; 4];
572 let s = c.encode_utf8(&mut buf);
573 self.write_str(s)
574 }
575 facet_format::ScalarValue::I64(n) => write_varint_signed(n, &mut self.writer),
576 facet_format::ScalarValue::U64(n) => write_varint(n, &mut self.writer),
577 facet_format::ScalarValue::I128(n) => write_varint_signed_i128(n, &mut self.writer),
578 facet_format::ScalarValue::U128(n) => write_varint_u128(n, &mut self.writer),
579 facet_format::ScalarValue::F64(n) => self.writer.write_bytes(&n.to_le_bytes()),
580 facet_format::ScalarValue::Str(s) => match s {
581 Cow::Borrowed(s) => self.write_str_borrowed(s),
582 Cow::Owned(s) => self.write_str(&s),
583 },
584 facet_format::ScalarValue::Bytes(bytes) => match bytes {
585 Cow::Borrowed(bytes) => self.write_bytes_borrowed(bytes),
586 Cow::Owned(bytes) => self.write_bytes(&bytes),
587 },
588 }
589 }
590
591 fn struct_field_mode(&self) -> StructFieldMode {
592 StructFieldMode::Unnamed
593 }
594
595 fn map_encoding(&self) -> MapEncoding {
596 MapEncoding::Pairs
597 }
598
599 fn enum_variant_encoding(&self) -> EnumVariantEncoding {
600 EnumVariantEncoding::Index
601 }
602
603 fn is_self_describing(&self) -> bool {
604 false
605 }
606
607 fn dynamic_value_encoding(&self) -> DynamicValueEncoding {
608 DynamicValueEncoding::Tagged
609 }
610
611 fn dynamic_value_tag(&mut self, tag: DynamicValueTag) -> Result<(), Self::Error> {
612 self.write_dynamic_tag(tag)
613 }
614
615 fn begin_seq_with_len(&mut self, len: usize) -> Result<(), Self::Error> {
616 write_varint(len as u64, &mut self.writer)
617 }
618
619 fn begin_map_with_len(&mut self, len: usize) -> Result<(), Self::Error> {
620 write_varint(len as u64, &mut self.writer)
621 }
622
623 fn end_map(&mut self) -> Result<(), Self::Error> {
624 Ok(())
625 }
626
627 fn typed_scalar(
628 &mut self,
629 scalar_type: ScalarType,
630 value: Peek<'_, '_>,
631 ) -> Result<(), Self::Error> {
632 match scalar_type {
633 ScalarType::Unit => Ok(()),
634 ScalarType::Bool => {
635 let v = *value.get::<bool>().map_err(|e| {
636 SerializeError::Custom(alloc::format!("Failed to get bool: {}", e))
637 })?;
638 self.writer.write_byte(if v { 1 } else { 0 })
639 }
640 ScalarType::Char => {
641 let c = *value.get::<char>().map_err(|e| {
642 SerializeError::Custom(alloc::format!("Failed to get char: {}", e))
643 })?;
644 let mut buf = [0u8; 4];
645 let s = c.encode_utf8(&mut buf);
646 self.write_str(s)
647 }
648 ScalarType::Str | ScalarType::String | ScalarType::CowStr => {
649 let s = value
650 .as_str()
651 .ok_or_else(|| SerializeError::Custom("Failed to get string value".into()))?;
652 self.write_str_borrowed(s)
653 }
654 ScalarType::F32 => {
655 let v = *value.get::<f32>().map_err(|e| {
656 SerializeError::Custom(alloc::format!("Failed to get f32: {}", e))
657 })?;
658 self.writer.write_bytes(&v.to_le_bytes())
659 }
660 ScalarType::F64 => {
661 let v = *value.get::<f64>().map_err(|e| {
662 SerializeError::Custom(alloc::format!("Failed to get f64: {}", e))
663 })?;
664 self.writer.write_bytes(&v.to_le_bytes())
665 }
666 ScalarType::U8 => {
667 let v = *value.get::<u8>().map_err(|e| {
668 SerializeError::Custom(alloc::format!("Failed to get u8: {}", e))
669 })?;
670 self.writer.write_byte(v)
671 }
672 ScalarType::U16 => {
673 let v = *value.get::<u16>().map_err(|e| {
674 SerializeError::Custom(alloc::format!("Failed to get u16: {}", e))
675 })?;
676 write_varint(v as u64, &mut self.writer)
677 }
678 ScalarType::U32 => {
679 let v = *value.get::<u32>().map_err(|e| {
680 SerializeError::Custom(alloc::format!("Failed to get u32: {}", e))
681 })?;
682 write_varint(v as u64, &mut self.writer)
683 }
684 ScalarType::U64 => {
685 let v = *value.get::<u64>().map_err(|e| {
686 SerializeError::Custom(alloc::format!("Failed to get u64: {}", e))
687 })?;
688 write_varint(v, &mut self.writer)
689 }
690 ScalarType::U128 => {
691 let v = *value.get::<u128>().map_err(|e| {
692 SerializeError::Custom(alloc::format!("Failed to get u128: {}", e))
693 })?;
694 write_varint_u128(v, &mut self.writer)
695 }
696 ScalarType::USize => {
697 let v = *value.get::<usize>().map_err(|e| {
698 SerializeError::Custom(alloc::format!("Failed to get usize: {}", e))
699 })?;
700 write_varint(v as u64, &mut self.writer)
701 }
702 ScalarType::I8 => {
703 let v = *value.get::<i8>().map_err(|e| {
704 SerializeError::Custom(alloc::format!("Failed to get i8: {}", e))
705 })?;
706 self.writer.write_byte(v as u8)
707 }
708 ScalarType::I16 => {
709 let v = *value.get::<i16>().map_err(|e| {
710 SerializeError::Custom(alloc::format!("Failed to get i16: {}", e))
711 })?;
712 write_varint_signed(v as i64, &mut self.writer)
713 }
714 ScalarType::I32 => {
715 let v = *value.get::<i32>().map_err(|e| {
716 SerializeError::Custom(alloc::format!("Failed to get i32: {}", e))
717 })?;
718 write_varint_signed(v as i64, &mut self.writer)
719 }
720 ScalarType::I64 => {
721 let v = *value.get::<i64>().map_err(|e| {
722 SerializeError::Custom(alloc::format!("Failed to get i64: {}", e))
723 })?;
724 write_varint_signed(v, &mut self.writer)
725 }
726 ScalarType::I128 => {
727 let v = *value.get::<i128>().map_err(|e| {
728 SerializeError::Custom(alloc::format!("Failed to get i128: {}", e))
729 })?;
730 write_varint_signed_i128(v, &mut self.writer)
731 }
732 ScalarType::ISize => {
733 let v = *value.get::<isize>().map_err(|e| {
734 SerializeError::Custom(alloc::format!("Failed to get isize: {}", e))
735 })?;
736 write_varint_signed(v as i64, &mut self.writer)
737 }
738 #[cfg(feature = "net")]
739 ScalarType::SocketAddr => {
740 let v = *value.get::<core::net::SocketAddr>().map_err(|e| {
741 SerializeError::Custom(alloc::format!("Failed to get SocketAddr: {}", e))
742 })?;
743 self.write_str(&v.to_string())
744 }
745 #[cfg(feature = "net")]
746 ScalarType::IpAddr => {
747 let v = *value.get::<core::net::IpAddr>().map_err(|e| {
748 SerializeError::Custom(alloc::format!("Failed to get IpAddr: {}", e))
749 })?;
750 self.write_str(&v.to_string())
751 }
752 #[cfg(feature = "net")]
753 ScalarType::Ipv4Addr => {
754 let v = *value.get::<core::net::Ipv4Addr>().map_err(|e| {
755 SerializeError::Custom(alloc::format!("Failed to get Ipv4Addr: {}", e))
756 })?;
757 self.write_str(&v.to_string())
758 }
759 #[cfg(feature = "net")]
760 ScalarType::Ipv6Addr => {
761 let v = *value.get::<core::net::Ipv6Addr>().map_err(|e| {
762 SerializeError::Custom(alloc::format!("Failed to get Ipv6Addr: {}", e))
763 })?;
764 self.write_str(&v.to_string())
765 }
766 _ => Err(SerializeError::Custom(alloc::format!(
767 "Unsupported scalar type: {:?}",
768 scalar_type
769 ))),
770 }
771 }
772
773 fn begin_option_some(&mut self) -> Result<(), Self::Error> {
774 self.writer.write_byte(1)
775 }
776
777 fn serialize_none(&mut self) -> Result<(), Self::Error> {
778 self.writer.write_byte(0)
779 }
780
781 fn begin_enum_variant(
782 &mut self,
783 variant_index: usize,
784 _variant_name: &'static str,
785 ) -> Result<(), Self::Error> {
786 write_varint(variant_index as u64, &mut self.writer)
787 }
788
789 fn serialize_byte_sequence(&mut self, bytes: &[u8]) -> Result<bool, Self::Error> {
790 self.write_bytes_borrowed(bytes)?;
792 Ok(true)
793 }
794
795 fn serialize_byte_array(&mut self, bytes: &[u8]) -> Result<bool, Self::Error> {
796 self.write_byte_array_borrowed(bytes)?;
798 Ok(true)
799 }
800
801 fn serialize_opaque_scalar(
802 &mut self,
803 shape: &'static facet_core::Shape,
804 value: Peek<'_, '_>,
805 ) -> Result<bool, Self::Error> {
806 self.serialize_opaque_scalar_with_field(None, shape, value)
807 }
808
809 fn serialize_opaque_scalar_with_field(
810 &mut self,
811 field: Option<&facet_core::Field>,
812 shape: &'static facet_core::Shape,
813 value: Peek<'_, '_>,
814 ) -> Result<bool, Self::Error> {
815 if value.scalar_type().is_some() {
816 return Ok(false);
817 }
818
819 if let Some(adapter) = shape.opaque_adapter {
820 let mapped = unsafe { (adapter.serialize)(value.data()) };
821 let mapped_peek = unsafe { Peek::unchecked_new(mapped.ptr, mapped.shape) };
822 if has_trailing_attr(field) {
823 serialize_root(self, mapped_peek).map_err(map_format_error)?;
826 } else {
827 let mut bytes = Vec::new();
828 let mut mapped_serializer = PostcardSerializer::new(CopyWriter::new(&mut bytes));
829 serialize_root(&mut mapped_serializer, mapped_peek).map_err(map_format_error)?;
830 self.write_bytes(&bytes)?;
831 }
832 return Ok(true);
833 }
834
835 #[cfg(feature = "camino")]
837 if shape.is_type::<camino::Utf8PathBuf>() {
838 use camino::Utf8PathBuf;
839 let path = value.get::<Utf8PathBuf>().map_err(|e| {
840 SerializeError::Custom(alloc::format!("Failed to get Utf8PathBuf: {}", e))
841 })?;
842 self.write_str(path.as_str())?;
843 return Ok(true);
844 }
845 #[cfg(feature = "camino")]
846 if shape.id == facet_core::Shape::id_of::<camino::Utf8Path>() {
847 use camino::Utf8Path;
848 let path = value.get::<Utf8Path>().map_err(|e| {
849 SerializeError::Custom(alloc::format!("Failed to get Utf8Path: {}", e))
850 })?;
851 self.write_str(path.as_str())?;
852 return Ok(true);
853 }
854
855 #[cfg(feature = "uuid")]
857 if shape.is_type::<uuid::Uuid>() {
858 use uuid::Uuid;
859 let uuid = value
860 .get::<Uuid>()
861 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get Uuid: {}", e)))?;
862 self.writer.write_bytes(uuid.as_bytes())?;
863 return Ok(true);
864 }
865
866 #[cfg(feature = "ulid")]
868 if shape.is_type::<ulid::Ulid>() {
869 use ulid::Ulid;
870 let ulid = value
871 .get::<Ulid>()
872 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get Ulid: {}", e)))?;
873 self.writer.write_bytes(&ulid.to_bytes())?;
874 return Ok(true);
875 }
876
877 #[cfg(feature = "jiff02")]
879 if shape.is_type::<jiff::Zoned>() {
880 use jiff::Zoned;
881 let zoned = value.get::<Zoned>().map_err(|e| {
882 SerializeError::Custom(alloc::format!("Failed to get Zoned: {}", e))
883 })?;
884 self.write_str(&zoned.to_string())?;
885 return Ok(true);
886 }
887 #[cfg(feature = "jiff02")]
888 if shape.is_type::<jiff::Timestamp>() {
889 use jiff::Timestamp;
890 let ts = value.get::<Timestamp>().map_err(|e| {
891 SerializeError::Custom(alloc::format!("Failed to get Timestamp: {}", e))
892 })?;
893 self.write_str(&ts.to_string())?;
894 return Ok(true);
895 }
896 #[cfg(feature = "jiff02")]
897 if shape.is_type::<jiff::civil::DateTime>() {
898 use jiff::civil::DateTime;
899 let dt = value.get::<DateTime>().map_err(|e| {
900 SerializeError::Custom(alloc::format!("Failed to get DateTime: {}", e))
901 })?;
902 self.write_str(&dt.to_string())?;
903 return Ok(true);
904 }
905
906 #[cfg(feature = "chrono")]
908 if shape.is_type::<chrono::DateTime<chrono::Utc>>() {
909 use chrono::{DateTime, SecondsFormat, Utc};
910 let dt = value.get::<DateTime<Utc>>().map_err(|e| {
911 SerializeError::Custom(alloc::format!("Failed to get DateTime<Utc>: {}", e))
912 })?;
913 self.write_str(&dt.to_rfc3339_opts(SecondsFormat::AutoSi, true))?;
914 return Ok(true);
915 }
916 #[cfg(feature = "chrono")]
917 if shape.is_type::<chrono::DateTime<chrono::Local>>() {
918 use chrono::{DateTime, Local, SecondsFormat};
919 let dt = value.get::<DateTime<Local>>().map_err(|e| {
920 SerializeError::Custom(alloc::format!("Failed to get DateTime<Local>: {}", e))
921 })?;
922 self.write_str(&dt.to_rfc3339_opts(SecondsFormat::AutoSi, false))?;
923 return Ok(true);
924 }
925 #[cfg(feature = "chrono")]
926 if shape.is_type::<chrono::DateTime<chrono::FixedOffset>>() {
927 use chrono::{DateTime, FixedOffset, SecondsFormat};
928 let dt = value.get::<DateTime<FixedOffset>>().map_err(|e| {
929 SerializeError::Custom(alloc::format!("Failed to get DateTime<FixedOffset>: {}", e))
930 })?;
931 self.write_str(&dt.to_rfc3339_opts(SecondsFormat::AutoSi, false))?;
932 return Ok(true);
933 }
934 #[cfg(feature = "chrono")]
935 if shape.is_type::<chrono::NaiveDateTime>() {
936 use chrono::NaiveDateTime;
937 let dt = value.get::<NaiveDateTime>().map_err(|e| {
938 SerializeError::Custom(alloc::format!("Failed to get NaiveDateTime: {}", e))
939 })?;
940 self.write_str(&dt.format("%Y-%m-%dT%H:%M:%S").to_string())?;
941 return Ok(true);
942 }
943 #[cfg(feature = "chrono")]
944 if shape.is_type::<chrono::NaiveDate>() {
945 use chrono::NaiveDate;
946 let date = value.get::<NaiveDate>().map_err(|e| {
947 SerializeError::Custom(alloc::format!("Failed to get NaiveDate: {}", e))
948 })?;
949 self.write_str(&date.to_string())?;
950 return Ok(true);
951 }
952 #[cfg(feature = "chrono")]
953 if shape.is_type::<chrono::NaiveTime>() {
954 use chrono::NaiveTime;
955 let time = value.get::<NaiveTime>().map_err(|e| {
956 SerializeError::Custom(alloc::format!("Failed to get NaiveTime: {}", e))
957 })?;
958 self.write_str(&time.to_string())?;
959 return Ok(true);
960 }
961
962 #[cfg(feature = "time")]
964 if shape.is_type::<time::UtcDateTime>() {
965 use time::UtcDateTime;
966 let dt = value.get::<UtcDateTime>().map_err(|e| {
967 SerializeError::Custom(alloc::format!("Failed to get UtcDateTime: {}", e))
968 })?;
969 let s = dt
970 .format(&time::format_description::well_known::Rfc3339)
971 .unwrap_or_else(|_| "<invalid>".to_string());
972 self.write_str(&s)?;
973 return Ok(true);
974 }
975 #[cfg(feature = "time")]
976 if shape.is_type::<time::OffsetDateTime>() {
977 use time::OffsetDateTime;
978 let dt = value.get::<OffsetDateTime>().map_err(|e| {
979 SerializeError::Custom(alloc::format!("Failed to get OffsetDateTime: {}", e))
980 })?;
981 let s = dt
982 .format(&time::format_description::well_known::Rfc3339)
983 .unwrap_or_else(|_| "<invalid>".to_string());
984 self.write_str(&s)?;
985 return Ok(true);
986 }
987
988 #[cfg(feature = "ordered-float")]
990 if shape.is_type::<ordered_float::OrderedFloat<f32>>() {
991 use ordered_float::OrderedFloat;
992 let val = value.get::<OrderedFloat<f32>>().map_err(|e| {
993 SerializeError::Custom(alloc::format!("Failed to get OrderedFloat<f32>: {}", e))
994 })?;
995 self.writer.write_bytes(&val.0.to_le_bytes())?;
996 return Ok(true);
997 } else if shape.is_type::<ordered_float::OrderedFloat<f64>>() {
998 use ordered_float::OrderedFloat;
999 let val = value.get::<OrderedFloat<f64>>().map_err(|e| {
1000 SerializeError::Custom(alloc::format!("Failed to get OrderedFloat<f64>: {}", e))
1001 })?;
1002 self.writer.write_bytes(&val.0.to_le_bytes())?;
1003 return Ok(true);
1004 }
1005
1006 #[cfg(feature = "ordered-float")]
1008 if shape.is_type::<ordered_float::NotNan<f32>>() {
1009 use ordered_float::NotNan;
1010 let val = value.get::<NotNan<f32>>().map_err(|e| {
1011 SerializeError::Custom(alloc::format!("Failed to get NotNan<f32>: {}", e))
1012 })?;
1013 self.writer.write_bytes(&val.into_inner().to_le_bytes())?;
1014 return Ok(true);
1015 } else if shape.is_type::<ordered_float::NotNan<f64>>() {
1016 use ordered_float::NotNan;
1017 let val = value.get::<NotNan<f64>>().map_err(|e| {
1018 SerializeError::Custom(alloc::format!("Failed to get NotNan<f64>: {}", e))
1019 })?;
1020 self.writer.write_bytes(&val.into_inner().to_le_bytes())?;
1021 return Ok(true);
1022 }
1023
1024 #[cfg(feature = "bytestring")]
1026 if shape == <bytestring::ByteString as facet_core::Facet>::SHAPE {
1027 let bs = value.get::<bytestring::ByteString>().map_err(|e| {
1028 SerializeError::Custom(alloc::format!("Failed to get ByteString: {}", e))
1029 })?;
1030 self.write_str(bs.as_ref())?;
1031 return Ok(true);
1032 }
1033
1034 #[cfg(feature = "compact_str")]
1036 if shape == <compact_str::CompactString as facet_core::Facet>::SHAPE {
1037 let cs = value.get::<compact_str::CompactString>().map_err(|e| {
1038 SerializeError::Custom(alloc::format!("Failed to get CompactString: {}", e))
1039 })?;
1040 self.write_str(cs.as_str())?;
1041 return Ok(true);
1042 }
1043
1044 #[cfg(feature = "smartstring")]
1046 if shape == <smartstring::SmartString<smartstring::LazyCompact> as facet_core::Facet>::SHAPE
1047 {
1048 let ss = value
1049 .get::<smartstring::SmartString<smartstring::LazyCompact>>()
1050 .map_err(|e| {
1051 SerializeError::Custom(alloc::format!("Failed to get SmartString: {}", e))
1052 })?;
1053 self.write_str(ss.as_str())?;
1054 return Ok(true);
1055 }
1056
1057 if shape.inner.is_some() {
1058 return Ok(false);
1059 }
1060
1061 if matches!(shape.def, Def::Scalar) {
1063 if let Some(s) = value.as_str() {
1064 self.write_str(s)?;
1065 return Ok(true);
1066 }
1067 if shape.vtable.has_display() {
1068 let s = alloc::format!("{}", value);
1069 self.write_str(&s)?;
1070 return Ok(true);
1071 }
1072 }
1073
1074 Ok(false)
1075 }
1076}
1077
1078fn write_varint<W: Writer>(mut value: u64, writer: &mut W) -> Result<(), SerializeError> {
1080 loop {
1081 let mut byte = (value & 0x7F) as u8;
1082 value >>= 7;
1083 if value != 0 {
1084 byte |= 0x80;
1085 }
1086 writer.write_byte(byte)?;
1087 if value == 0 {
1088 break;
1089 }
1090 }
1091 Ok(())
1092}
1093
1094fn write_varint_u128<W: Writer>(mut value: u128, writer: &mut W) -> Result<(), SerializeError> {
1096 loop {
1097 let mut byte = (value & 0x7F) as u8;
1098 value >>= 7;
1099 if value != 0 {
1100 byte |= 0x80;
1101 }
1102 writer.write_byte(byte)?;
1103 if value == 0 {
1104 break;
1105 }
1106 }
1107 Ok(())
1108}
1109
1110fn write_varint_signed<W: Writer>(value: i64, writer: &mut W) -> Result<(), SerializeError> {
1112 let encoded = ((value << 1) ^ (value >> 63)) as u64;
1114 write_varint(encoded, writer)
1115}
1116
1117fn write_varint_signed_i128<W: Writer>(value: i128, writer: &mut W) -> Result<(), SerializeError> {
1119 let encoded = ((value << 1) ^ (value >> 127)) as u128;
1121 write_varint_u128(encoded, writer)
1122}
1123
1124#[cfg(test)]
1125mod tests {
1126 use super::*;
1127 use facet::Facet;
1128 use facet_value::{VArray, VBytes, VNumber, VObject, VString, Value};
1129 use postcard::to_allocvec as postcard_to_vec;
1130 use serde::Serialize;
1131
1132 #[derive(Facet, Serialize, PartialEq, Debug)]
1133 struct SimpleStruct {
1134 a: u32,
1135 b: alloc::string::String,
1136 c: bool,
1137 }
1138
1139 #[test]
1140 fn test_simple_struct() {
1141 facet_testhelpers::setup();
1142
1143 let value = SimpleStruct {
1144 a: 123,
1145 b: "hello".into(),
1146 c: true,
1147 };
1148
1149 let facet_bytes = to_vec(&value).unwrap();
1150 let postcard_bytes = postcard_to_vec(&value).unwrap();
1151
1152 assert_eq!(facet_bytes, postcard_bytes);
1153 }
1154
1155 #[test]
1156 fn test_u8() {
1157 facet_testhelpers::setup();
1158
1159 #[derive(Facet, Serialize, PartialEq, Debug)]
1160 struct U8Struct {
1161 value: u8,
1162 }
1163
1164 let value = U8Struct { value: 42 };
1165 let facet_bytes = to_vec(&value).unwrap();
1166 let postcard_bytes = postcard_to_vec(&value).unwrap();
1167 assert_eq!(facet_bytes, postcard_bytes);
1168 }
1169
1170 #[test]
1171 fn test_i32() {
1172 facet_testhelpers::setup();
1173
1174 #[derive(Facet, Serialize, PartialEq, Debug)]
1175 struct I32Struct {
1176 value: i32,
1177 }
1178
1179 let value = I32Struct { value: -100000 };
1180 let facet_bytes = to_vec(&value).unwrap();
1181 let postcard_bytes = postcard_to_vec(&value).unwrap();
1182 assert_eq!(facet_bytes, postcard_bytes);
1183 }
1184
1185 #[test]
1186 fn test_string() {
1187 facet_testhelpers::setup();
1188
1189 #[derive(Facet, Serialize, PartialEq, Debug)]
1190 struct StringStruct {
1191 value: alloc::string::String,
1192 }
1193
1194 let value = StringStruct {
1195 value: "hello world".into(),
1196 };
1197 let facet_bytes = to_vec(&value).unwrap();
1198 let postcard_bytes = postcard_to_vec(&value).unwrap();
1199 assert_eq!(facet_bytes, postcard_bytes);
1200 }
1201
1202 #[test]
1203 fn test_vec() {
1204 facet_testhelpers::setup();
1205
1206 #[derive(Facet, Serialize, PartialEq, Debug)]
1207 struct VecStruct {
1208 values: Vec<u32>,
1209 }
1210
1211 let value = VecStruct {
1212 values: alloc::vec![1, 2, 3, 4, 5],
1213 };
1214 let facet_bytes = to_vec(&value).unwrap();
1215 let postcard_bytes = postcard_to_vec(&value).unwrap();
1216 assert_eq!(facet_bytes, postcard_bytes);
1217 }
1218
1219 #[test]
1220 fn test_vec_u8() {
1221 facet_testhelpers::setup();
1222
1223 #[derive(Facet, Serialize, PartialEq, Debug)]
1224 struct BytesStruct {
1225 data: Vec<u8>,
1226 }
1227
1228 let value = BytesStruct {
1229 data: alloc::vec![0, 1, 2, 3, 4, 5, 255, 128, 64],
1230 };
1231 let facet_bytes = to_vec(&value).unwrap();
1232 let postcard_bytes = postcard_to_vec(&value).unwrap();
1233 assert_eq!(facet_bytes, postcard_bytes);
1234
1235 let decoded: BytesStruct = crate::from_slice(&facet_bytes).unwrap();
1237 assert_eq!(decoded, value);
1238 }
1239
1240 #[test]
1241 fn test_vec_u8_large() {
1242 facet_testhelpers::setup();
1243
1244 #[derive(Facet, Serialize, PartialEq, Debug)]
1245 struct LargeBytes {
1246 data: Vec<u8>,
1247 }
1248
1249 let value = LargeBytes {
1251 data: (0..1000).map(|i| (i % 256) as u8).collect(),
1252 };
1253 let facet_bytes = to_vec(&value).unwrap();
1254 let postcard_bytes = postcard_to_vec(&value).unwrap();
1255 assert_eq!(facet_bytes, postcard_bytes);
1256
1257 let decoded: LargeBytes = crate::from_slice(&facet_bytes).unwrap();
1259 assert_eq!(decoded, value);
1260 }
1261
1262 #[test]
1263 fn test_vec_u8_empty() {
1264 facet_testhelpers::setup();
1265
1266 #[derive(Facet, Serialize, PartialEq, Debug)]
1267 struct EmptyBytes {
1268 data: Vec<u8>,
1269 }
1270
1271 let value = EmptyBytes {
1272 data: alloc::vec![],
1273 };
1274 let facet_bytes = to_vec(&value).unwrap();
1275 let postcard_bytes = postcard_to_vec(&value).unwrap();
1276 assert_eq!(facet_bytes, postcard_bytes);
1277
1278 let decoded: EmptyBytes = crate::from_slice(&facet_bytes).unwrap();
1280 assert_eq!(decoded, value);
1281 }
1282
1283 #[test]
1284 fn test_option_some() {
1285 facet_testhelpers::setup();
1286
1287 #[derive(Facet, Serialize, PartialEq, Debug)]
1288 struct OptionStruct {
1289 value: Option<u32>,
1290 }
1291
1292 let value = OptionStruct { value: Some(42) };
1293 let facet_bytes = to_vec(&value).unwrap();
1294 let postcard_bytes = postcard_to_vec(&value).unwrap();
1295 assert_eq!(facet_bytes, postcard_bytes);
1296 }
1297
1298 #[test]
1299 fn test_option_none() {
1300 facet_testhelpers::setup();
1301
1302 #[derive(Facet, Serialize, PartialEq, Debug)]
1303 struct OptionStruct {
1304 value: Option<u32>,
1305 }
1306
1307 let value = OptionStruct { value: None };
1308 let facet_bytes = to_vec(&value).unwrap();
1309 let postcard_bytes = postcard_to_vec(&value).unwrap();
1310 assert_eq!(facet_bytes, postcard_bytes);
1311 }
1312
1313 #[test]
1314 fn test_unit_enum() {
1315 facet_testhelpers::setup();
1316
1317 #[derive(Facet, Serialize, PartialEq, Debug)]
1318 #[repr(C)]
1319 enum Color {
1320 Red,
1321 Green,
1322 Blue,
1323 }
1324
1325 let facet_bytes = to_vec(&Color::Red).unwrap();
1326 let postcard_bytes = postcard_to_vec(&Color::Red).unwrap();
1327 assert_eq!(facet_bytes, postcard_bytes);
1328
1329 let facet_bytes = to_vec(&Color::Green).unwrap();
1330 let postcard_bytes = postcard_to_vec(&Color::Green).unwrap();
1331 assert_eq!(facet_bytes, postcard_bytes);
1332
1333 let facet_bytes = to_vec(&Color::Blue).unwrap();
1334 let postcard_bytes = postcard_to_vec(&Color::Blue).unwrap();
1335 assert_eq!(facet_bytes, postcard_bytes);
1336 }
1337
1338 #[test]
1339 fn test_tuple_enum() {
1340 facet_testhelpers::setup();
1341
1342 #[derive(Facet, Serialize, PartialEq, Debug)]
1343 #[repr(C)]
1344 enum Value {
1345 Int(i32),
1346 Text(alloc::string::String),
1347 }
1348
1349 let facet_bytes = to_vec(&Value::Int(42)).unwrap();
1350 let postcard_bytes = postcard_to_vec(&Value::Int(42)).unwrap();
1351 assert_eq!(facet_bytes, postcard_bytes);
1352
1353 let facet_bytes = to_vec(&Value::Text("hello".into())).unwrap();
1354 let postcard_bytes = postcard_to_vec(&Value::Text("hello".into())).unwrap();
1355 assert_eq!(facet_bytes, postcard_bytes);
1356 }
1357
1358 #[test]
1359 fn test_struct_enum() {
1360 facet_testhelpers::setup();
1361
1362 #[derive(Facet, Serialize, PartialEq, Debug)]
1363 #[repr(C)]
1364 enum Message {
1365 Quit,
1366 Move { x: i32, y: i32 },
1367 }
1368
1369 let facet_bytes = to_vec(&Message::Quit).unwrap();
1370 let postcard_bytes = postcard_to_vec(&Message::Quit).unwrap();
1371 assert_eq!(facet_bytes, postcard_bytes);
1372
1373 let facet_bytes = to_vec(&Message::Move { x: 10, y: 20 }).unwrap();
1374 let postcard_bytes = postcard_to_vec(&Message::Move { x: 10, y: 20 }).unwrap();
1375 assert_eq!(facet_bytes, postcard_bytes);
1376 }
1377
1378 #[test]
1379 fn test_to_writer_fallible() {
1380 facet_testhelpers::setup();
1381
1382 struct CustomWriter {
1383 buffer: Vec<u8>,
1384 }
1385
1386 impl Writer for CustomWriter {
1387 fn write_byte(&mut self, byte: u8) -> Result<(), SerializeError> {
1388 self.buffer.push(byte);
1389 Ok(())
1390 }
1391
1392 fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError> {
1393 self.buffer.extend_from_slice(bytes);
1394 Ok(())
1395 }
1396 }
1397
1398 let value = SimpleStruct {
1399 a: 123,
1400 b: "hello".into(),
1401 c: true,
1402 };
1403
1404 let mut writer = CustomWriter { buffer: Vec::new() };
1405 to_writer_fallible(&value, &mut writer).unwrap();
1406
1407 let postcard_bytes = postcard_to_vec(&value).unwrap();
1408 assert_eq!(writer.buffer, postcard_bytes);
1409 }
1410
1411 #[test]
1412 fn test_value_roundtrip() {
1413 facet_testhelpers::setup();
1414
1415 let mut array = VArray::new();
1416 array.push(Value::from(VNumber::from_i64(1)));
1417 array.push(Value::from(VString::new("two")));
1418 array.push(Value::TRUE);
1419
1420 let mut object = VObject::new();
1421 object.insert("n", Value::from(VNumber::from_u64(42)));
1422 object.insert("s", Value::from(VString::new("hello")));
1423 object.insert("b", Value::from(VBytes::new(&[1, 2, 3])));
1424 object.insert("a", Value::from(array));
1425
1426 let value = Value::from(object);
1427 let bytes = to_vec(&value).unwrap();
1428 let decoded: Value = crate::from_slice(&bytes).unwrap();
1429
1430 assert_eq!(decoded, value);
1431 }
1432
1433 #[test]
1434 fn test_to_vec_with_shape_struct() {
1435 facet_testhelpers::setup();
1436
1437 #[derive(Debug, Facet, PartialEq, Serialize)]
1438 struct Point {
1439 x: i32,
1440 y: i32,
1441 }
1442
1443 let value: Value = facet_json::from_str(r#"{"x": 10, "y": 20}"#).unwrap();
1445
1446 let bytes = to_vec_with_shape(&value, Point::SHAPE).unwrap();
1448
1449 let expected = to_vec(&Point { x: 10, y: 20 }).unwrap();
1451 assert_eq!(bytes, expected);
1452
1453 let point: Point = crate::from_slice(&bytes).unwrap();
1455 assert_eq!(point, Point { x: 10, y: 20 });
1456 }
1457
1458 #[test]
1459 fn test_to_vec_with_shape_vec() {
1460 facet_testhelpers::setup();
1461
1462 let value: Value = facet_json::from_str(r#"[1, 2, 3, 4, 5]"#).unwrap();
1464
1465 let bytes = to_vec_with_shape(&value, <Vec<i32>>::SHAPE).unwrap();
1467
1468 let expected = to_vec(&alloc::vec![1i32, 2, 3, 4, 5]).unwrap();
1470 assert_eq!(bytes, expected);
1471
1472 let result: Vec<i32> = crate::from_slice(&bytes).unwrap();
1474 assert_eq!(result, alloc::vec![1, 2, 3, 4, 5]);
1475 }
1476
1477 #[test]
1478 fn test_to_vec_with_shape_nested() {
1479 facet_testhelpers::setup();
1480
1481 #[derive(Debug, Facet, PartialEq, Serialize)]
1482 struct Nested {
1483 items: Vec<Item>,
1484 }
1485
1486 #[derive(Debug, Facet, PartialEq, Serialize)]
1487 struct Item {
1488 name: alloc::string::String,
1489 count: u32,
1490 }
1491
1492 let value: Value = facet_json::from_str(
1494 r#"{"items": [{"name": "foo", "count": 10}, {"name": "bar", "count": 20}]}"#,
1495 )
1496 .unwrap();
1497
1498 let bytes = to_vec_with_shape(&value, Nested::SHAPE).unwrap();
1500
1501 let result: Nested = crate::from_slice(&bytes).unwrap();
1503 assert_eq!(
1504 result,
1505 Nested {
1506 items: alloc::vec![
1507 Item {
1508 name: "foo".into(),
1509 count: 10
1510 },
1511 Item {
1512 name: "bar".into(),
1513 count: 20
1514 }
1515 ]
1516 }
1517 );
1518 }
1519
1520 #[test]
1521 fn test_to_vec_with_shape_roundtrip() {
1522 facet_testhelpers::setup();
1523
1524 #[derive(Debug, Facet, PartialEq, Serialize)]
1525 struct Config {
1526 name: alloc::string::String,
1527 enabled: bool,
1528 count: u32,
1529 }
1530
1531 let original = Config {
1533 name: "test".into(),
1534 enabled: true,
1535 count: 42,
1536 };
1537
1538 let typed_bytes = to_vec(&original).unwrap();
1540
1541 let value: Value = crate::from_slice_with_shape(&typed_bytes, Config::SHAPE).unwrap();
1543
1544 let value_bytes = to_vec_with_shape(&value, Config::SHAPE).unwrap();
1546
1547 assert_eq!(typed_bytes, value_bytes);
1549
1550 let roundtrip: Config = crate::from_slice(&value_bytes).unwrap();
1552 assert_eq!(roundtrip, original);
1553 }
1554
1555 #[test]
1556 fn test_value_in_tuple() {
1557 facet_testhelpers::setup();
1558
1559 let tuple: (u64, alloc::string::String, Value) =
1562 (42, "hello".into(), Value::from(VNumber::from_i64(123)));
1563
1564 let bytes = to_vec(&tuple).unwrap();
1565 let decoded: (u64, alloc::string::String, Value) = crate::from_slice(&bytes).unwrap();
1566
1567 assert_eq!(decoded.0, 42);
1568 assert_eq!(decoded.1, "hello");
1569 assert_eq!(decoded.2, Value::from(VNumber::from_i64(123)));
1570 }
1571
1572 #[test]
1573 fn test_value_in_struct() {
1574 facet_testhelpers::setup();
1575
1576 #[derive(Debug, Facet, PartialEq)]
1577 struct WithValue {
1578 id: u64,
1579 name: alloc::string::String,
1580 data: Value,
1581 }
1582
1583 let original = WithValue {
1584 id: 1,
1585 name: "test".into(),
1586 data: Value::from(VObject::from_iter([(
1587 "key".to_string(),
1588 Value::from(VString::new("value")),
1589 )])),
1590 };
1591
1592 let bytes = to_vec(&original).unwrap();
1593 let decoded: WithValue = crate::from_slice(&bytes).unwrap();
1594
1595 assert_eq!(decoded, original);
1596 }
1597
1598 #[test]
1599 fn test_value_nested_in_struct() {
1600 facet_testhelpers::setup();
1601
1602 #[derive(Debug, Facet, PartialEq)]
1603 struct Outer {
1604 before: u32,
1605 value: Value,
1606 after: u32,
1607 }
1608
1609 let mut obj = VObject::new();
1611 obj.insert("nested", Value::from(VNumber::from_i64(99)));
1612 obj.insert("str", Value::from(VString::new("test")));
1613
1614 let original = Outer {
1615 before: 10,
1616 value: Value::from(obj),
1617 after: 20,
1618 };
1619
1620 let bytes = to_vec(&original).unwrap();
1621 let decoded: Outer = crate::from_slice(&bytes).unwrap();
1622 assert_eq!(decoded, original);
1623
1624 let mut arr = VArray::new();
1626 arr.push(Value::from(VNumber::from_i64(1)));
1627 arr.push(Value::from(VString::new("two")));
1628 arr.push(Value::TRUE);
1629
1630 let original = Outer {
1631 before: 100,
1632 value: Value::from(arr),
1633 after: 200,
1634 };
1635
1636 let bytes = to_vec(&original).unwrap();
1637 let decoded: Outer = crate::from_slice(&bytes).unwrap();
1638 assert_eq!(decoded, original);
1639 }
1640
1641 #[test]
1647 fn test_skip_all_unless_truthy_roundtrip() {
1648 facet_testhelpers::setup();
1649
1650 #[derive(Debug, Clone, PartialEq, Facet)]
1651 #[facet(skip_all_unless_truthy)]
1652 pub struct Value {
1653 pub tag: Option<alloc::string::String>,
1654 pub payload: Option<alloc::string::String>,
1655 }
1656
1657 let v = Value {
1659 tag: None,
1660 payload: Some("hello".into()),
1661 };
1662
1663 let bytes = to_vec(&v).expect("serialize");
1664 let v2: Value = crate::from_slice(&bytes).expect("deserialize");
1665 assert_eq!(v, v2);
1666
1667 let v = Value {
1669 tag: None,
1670 payload: None,
1671 };
1672 let bytes = to_vec(&v).expect("serialize");
1673 let v2: Value = crate::from_slice(&bytes).expect("deserialize");
1674 assert_eq!(v, v2);
1675
1676 let v = Value {
1678 tag: Some("mytag".into()),
1679 payload: Some("mypayload".into()),
1680 };
1681 let bytes = to_vec(&v).expect("serialize");
1682 let v2: Value = crate::from_slice(&bytes).expect("deserialize");
1683 assert_eq!(v, v2);
1684
1685 let v = Value {
1687 tag: Some("mytag".into()),
1688 payload: None,
1689 };
1690 let bytes = to_vec(&v).expect("serialize");
1691 let v2: Value = crate::from_slice(&bytes).expect("deserialize");
1692 assert_eq!(v, v2);
1693 }
1694}