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