1extern crate alloc;
12
13use alloc::vec::Vec;
14
15use facet_core::{Def, ScalarType};
16use facet_format::{
17 DynamicValueEncoding, DynamicValueTag, EnumVariantEncoding, FormatSerializer, MapEncoding,
18 SerializeError as FormatSerializeError, StructFieldMode, serialize_root,
19};
20use facet_reflect::Peek;
21
22use crate::error::SerializeError;
23
24pub trait Writer {
74 fn write_byte(&mut self, byte: u8) -> Result<(), SerializeError>;
76
77 fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError>;
79}
80
81impl Writer for Vec<u8> {
82 fn write_byte(&mut self, byte: u8) -> Result<(), SerializeError> {
83 self.push(byte);
84 Ok(())
85 }
86
87 fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError> {
88 self.extend_from_slice(bytes);
89 Ok(())
90 }
91}
92
93pub fn to_vec<T>(value: &T) -> Result<Vec<u8>, SerializeError>
110where
111 T: facet_core::Facet<'static>,
112{
113 let mut buffer = Vec::new();
114 to_writer_fallible(value, &mut buffer)?;
115 Ok(buffer)
116}
117
118pub fn to_writer_fallible<T, W>(value: &T, writer: &mut W) -> Result<(), SerializeError>
157where
158 T: facet_core::Facet<'static>,
159 W: Writer,
160{
161 let peek = Peek::new(value);
162 let mut serializer = PostcardSerializer::new(writer);
163 serialize_root(&mut serializer, peek).map_err(map_format_error)
164}
165
166pub fn peek_to_vec(peek: Peek<'_, '_>) -> Result<Vec<u8>, SerializeError> {
188 let mut buffer = Vec::new();
189 let mut serializer = PostcardSerializer::new(&mut buffer);
190 serialize_root(&mut serializer, peek).map_err(map_format_error)?;
191 Ok(buffer)
192}
193
194fn map_format_error(error: FormatSerializeError<SerializeError>) -> SerializeError {
195 match error {
196 FormatSerializeError::Backend(err) => err,
197 FormatSerializeError::Reflect(err) => SerializeError::Custom(alloc::format!("{err}")),
198 FormatSerializeError::Unsupported(message) => SerializeError::Custom(message.into_owned()),
199 FormatSerializeError::Internal(message) => SerializeError::Custom(message.into_owned()),
200 }
201}
202
203struct PostcardSerializer<'a, W> {
204 writer: &'a mut W,
205}
206
207impl<'a, W> PostcardSerializer<'a, W> {
208 fn new(writer: &'a mut W) -> Self {
209 Self { writer }
210 }
211
212 fn write_str(&mut self, s: &str) -> Result<(), SerializeError>
213 where
214 W: Writer,
215 {
216 write_varint(s.len() as u64, self.writer)?;
217 self.writer.write_bytes(s.as_bytes())
218 }
219
220 fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError>
221 where
222 W: Writer,
223 {
224 write_varint(bytes.len() as u64, self.writer)?;
225 self.writer.write_bytes(bytes)
226 }
227
228 fn write_dynamic_tag(&mut self, tag: DynamicValueTag) -> Result<(), SerializeError>
229 where
230 W: Writer,
231 {
232 let byte = match tag {
233 DynamicValueTag::Null => 0,
234 DynamicValueTag::Bool => 1,
235 DynamicValueTag::I64 => 2,
236 DynamicValueTag::U64 => 3,
237 DynamicValueTag::F64 => 4,
238 DynamicValueTag::String => 5,
239 DynamicValueTag::Bytes => 6,
240 DynamicValueTag::Array => 7,
241 DynamicValueTag::Object => 8,
242 DynamicValueTag::DateTime => 9,
243 };
244 self.writer.write_byte(byte)
245 }
246}
247
248impl<W: Writer> FormatSerializer for PostcardSerializer<'_, W> {
249 type Error = SerializeError;
250
251 fn begin_struct(&mut self) -> Result<(), Self::Error> {
252 Ok(())
253 }
254
255 fn field_key(&mut self, _key: &str) -> Result<(), Self::Error> {
256 Err(SerializeError::Custom(
257 "postcard does not support named fields".into(),
258 ))
259 }
260
261 fn end_struct(&mut self) -> Result<(), Self::Error> {
262 Ok(())
263 }
264
265 fn begin_seq(&mut self) -> Result<(), Self::Error> {
266 Ok(())
267 }
268
269 fn end_seq(&mut self) -> Result<(), Self::Error> {
270 Ok(())
271 }
272
273 fn scalar(&mut self, scalar: facet_format::ScalarValue<'_>) -> Result<(), Self::Error> {
274 match scalar {
275 facet_format::ScalarValue::Null => Ok(()),
276 facet_format::ScalarValue::Bool(v) => self.writer.write_byte(if v { 1 } else { 0 }),
277 facet_format::ScalarValue::Char(c) => {
278 let mut buf = [0u8; 4];
280 let s = c.encode_utf8(&mut buf);
281 self.write_str(s)
282 }
283 facet_format::ScalarValue::I64(n) => write_varint_signed(n, self.writer),
284 facet_format::ScalarValue::U64(n) => write_varint(n, self.writer),
285 facet_format::ScalarValue::I128(n) => write_varint_signed_i128(n, self.writer),
286 facet_format::ScalarValue::U128(n) => write_varint_u128(n, self.writer),
287 facet_format::ScalarValue::F64(n) => self.writer.write_bytes(&n.to_le_bytes()),
288 facet_format::ScalarValue::Str(s) | facet_format::ScalarValue::StringlyTyped(s) => {
289 self.write_str(&s)
290 }
291 facet_format::ScalarValue::Bytes(bytes) => self.write_bytes(&bytes),
292 }
293 }
294
295 fn struct_field_mode(&self) -> StructFieldMode {
296 StructFieldMode::Unnamed
297 }
298
299 fn map_encoding(&self) -> MapEncoding {
300 MapEncoding::Pairs
301 }
302
303 fn enum_variant_encoding(&self) -> EnumVariantEncoding {
304 EnumVariantEncoding::Index
305 }
306
307 fn dynamic_value_encoding(&self) -> DynamicValueEncoding {
308 DynamicValueEncoding::Tagged
309 }
310
311 fn dynamic_value_tag(&mut self, tag: DynamicValueTag) -> Result<(), Self::Error> {
312 self.write_dynamic_tag(tag)
313 }
314
315 fn begin_seq_with_len(&mut self, len: usize) -> Result<(), Self::Error> {
316 write_varint(len as u64, self.writer)
317 }
318
319 fn begin_map_with_len(&mut self, len: usize) -> Result<(), Self::Error> {
320 write_varint(len as u64, self.writer)
321 }
322
323 fn end_map(&mut self) -> Result<(), Self::Error> {
324 Ok(())
325 }
326
327 fn typed_scalar(
328 &mut self,
329 scalar_type: ScalarType,
330 value: Peek<'_, '_>,
331 ) -> Result<(), Self::Error> {
332 match scalar_type {
333 ScalarType::Unit => Ok(()),
334 ScalarType::Bool => {
335 let v = *value.get::<bool>().map_err(|e| {
336 SerializeError::Custom(alloc::format!("Failed to get bool: {}", e))
337 })?;
338 self.writer.write_byte(if v { 1 } else { 0 })
339 }
340 ScalarType::Char => {
341 let c = *value.get::<char>().map_err(|e| {
342 SerializeError::Custom(alloc::format!("Failed to get char: {}", e))
343 })?;
344 let mut buf = [0u8; 4];
345 let s = c.encode_utf8(&mut buf);
346 self.write_str(s)
347 }
348 ScalarType::Str | ScalarType::String | ScalarType::CowStr => {
349 let s = value
350 .as_str()
351 .ok_or_else(|| SerializeError::Custom("Failed to get string value".into()))?;
352 self.write_str(s)
353 }
354 ScalarType::F32 => {
355 let v = *value.get::<f32>().map_err(|e| {
356 SerializeError::Custom(alloc::format!("Failed to get f32: {}", e))
357 })?;
358 self.writer.write_bytes(&v.to_le_bytes())
359 }
360 ScalarType::F64 => {
361 let v = *value.get::<f64>().map_err(|e| {
362 SerializeError::Custom(alloc::format!("Failed to get f64: {}", e))
363 })?;
364 self.writer.write_bytes(&v.to_le_bytes())
365 }
366 ScalarType::U8 => {
367 let v = *value.get::<u8>().map_err(|e| {
368 SerializeError::Custom(alloc::format!("Failed to get u8: {}", e))
369 })?;
370 self.writer.write_byte(v)
371 }
372 ScalarType::U16 => {
373 let v = *value.get::<u16>().map_err(|e| {
374 SerializeError::Custom(alloc::format!("Failed to get u16: {}", e))
375 })?;
376 write_varint(v as u64, self.writer)
377 }
378 ScalarType::U32 => {
379 let v = *value.get::<u32>().map_err(|e| {
380 SerializeError::Custom(alloc::format!("Failed to get u32: {}", e))
381 })?;
382 write_varint(v as u64, self.writer)
383 }
384 ScalarType::U64 => {
385 let v = *value.get::<u64>().map_err(|e| {
386 SerializeError::Custom(alloc::format!("Failed to get u64: {}", e))
387 })?;
388 write_varint(v, self.writer)
389 }
390 ScalarType::U128 => {
391 let v = *value.get::<u128>().map_err(|e| {
392 SerializeError::Custom(alloc::format!("Failed to get u128: {}", e))
393 })?;
394 write_varint_u128(v, self.writer)
395 }
396 ScalarType::USize => {
397 let v = *value.get::<usize>().map_err(|e| {
398 SerializeError::Custom(alloc::format!("Failed to get usize: {}", e))
399 })?;
400 write_varint(v as u64, self.writer)
401 }
402 ScalarType::I8 => {
403 let v = *value.get::<i8>().map_err(|e| {
404 SerializeError::Custom(alloc::format!("Failed to get i8: {}", e))
405 })?;
406 self.writer.write_byte(v as u8)
407 }
408 ScalarType::I16 => {
409 let v = *value.get::<i16>().map_err(|e| {
410 SerializeError::Custom(alloc::format!("Failed to get i16: {}", e))
411 })?;
412 write_varint_signed(v as i64, self.writer)
413 }
414 ScalarType::I32 => {
415 let v = *value.get::<i32>().map_err(|e| {
416 SerializeError::Custom(alloc::format!("Failed to get i32: {}", e))
417 })?;
418 write_varint_signed(v as i64, self.writer)
419 }
420 ScalarType::I64 => {
421 let v = *value.get::<i64>().map_err(|e| {
422 SerializeError::Custom(alloc::format!("Failed to get i64: {}", e))
423 })?;
424 write_varint_signed(v, self.writer)
425 }
426 ScalarType::I128 => {
427 let v = *value.get::<i128>().map_err(|e| {
428 SerializeError::Custom(alloc::format!("Failed to get i128: {}", e))
429 })?;
430 write_varint_signed_i128(v, self.writer)
431 }
432 ScalarType::ISize => {
433 let v = *value.get::<isize>().map_err(|e| {
434 SerializeError::Custom(alloc::format!("Failed to get isize: {}", e))
435 })?;
436 write_varint_signed(v as i64, self.writer)
437 }
438 #[cfg(feature = "net")]
439 ScalarType::SocketAddr => {
440 let v = *value.get::<core::net::SocketAddr>().map_err(|e| {
441 SerializeError::Custom(alloc::format!("Failed to get SocketAddr: {}", e))
442 })?;
443 self.write_str(&v.to_string())
444 }
445 #[cfg(feature = "net")]
446 ScalarType::IpAddr => {
447 let v = *value.get::<core::net::IpAddr>().map_err(|e| {
448 SerializeError::Custom(alloc::format!("Failed to get IpAddr: {}", e))
449 })?;
450 self.write_str(&v.to_string())
451 }
452 #[cfg(feature = "net")]
453 ScalarType::Ipv4Addr => {
454 let v = *value.get::<core::net::Ipv4Addr>().map_err(|e| {
455 SerializeError::Custom(alloc::format!("Failed to get Ipv4Addr: {}", e))
456 })?;
457 self.write_str(&v.to_string())
458 }
459 #[cfg(feature = "net")]
460 ScalarType::Ipv6Addr => {
461 let v = *value.get::<core::net::Ipv6Addr>().map_err(|e| {
462 SerializeError::Custom(alloc::format!("Failed to get Ipv6Addr: {}", e))
463 })?;
464 self.write_str(&v.to_string())
465 }
466 _ => Err(SerializeError::Custom(alloc::format!(
467 "Unsupported scalar type: {:?}",
468 scalar_type
469 ))),
470 }
471 }
472
473 fn begin_option_some(&mut self) -> Result<(), Self::Error> {
474 self.writer.write_byte(1)
475 }
476
477 fn serialize_none(&mut self) -> Result<(), Self::Error> {
478 self.writer.write_byte(0)
479 }
480
481 fn begin_enum_variant(
482 &mut self,
483 variant_index: usize,
484 _variant_name: &'static str,
485 ) -> Result<(), Self::Error> {
486 write_varint(variant_index as u64, self.writer)
487 }
488
489 fn serialize_opaque_scalar(
490 &mut self,
491 shape: &'static facet_core::Shape,
492 value: Peek<'_, '_>,
493 ) -> Result<bool, Self::Error> {
494 if value.scalar_type().is_some() {
495 return Ok(false);
496 }
497
498 #[cfg(feature = "camino")]
500 if shape.is_type::<camino::Utf8PathBuf>() {
501 use camino::Utf8PathBuf;
502 let path = value.get::<Utf8PathBuf>().map_err(|e| {
503 SerializeError::Custom(alloc::format!("Failed to get Utf8PathBuf: {}", e))
504 })?;
505 self.write_str(path.as_str())?;
506 return Ok(true);
507 }
508 #[cfg(feature = "camino")]
509 if shape.id == facet_core::Shape::id_of::<camino::Utf8Path>() {
510 use camino::Utf8Path;
511 let path = value.get::<Utf8Path>().map_err(|e| {
512 SerializeError::Custom(alloc::format!("Failed to get Utf8Path: {}", e))
513 })?;
514 self.write_str(path.as_str())?;
515 return Ok(true);
516 }
517
518 #[cfg(feature = "uuid")]
520 if shape.is_type::<uuid::Uuid>() {
521 use uuid::Uuid;
522 let uuid = value
523 .get::<Uuid>()
524 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get Uuid: {}", e)))?;
525 self.writer.write_bytes(uuid.as_bytes())?;
526 return Ok(true);
527 }
528
529 #[cfg(feature = "ulid")]
531 if shape.is_type::<ulid::Ulid>() {
532 use ulid::Ulid;
533 let ulid = value
534 .get::<Ulid>()
535 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get Ulid: {}", e)))?;
536 self.writer.write_bytes(&ulid.to_bytes())?;
537 return Ok(true);
538 }
539
540 #[cfg(feature = "jiff02")]
542 if shape.is_type::<jiff::Zoned>() {
543 use jiff::Zoned;
544 let zoned = value.get::<Zoned>().map_err(|e| {
545 SerializeError::Custom(alloc::format!("Failed to get Zoned: {}", e))
546 })?;
547 self.write_str(&zoned.to_string())?;
548 return Ok(true);
549 }
550 #[cfg(feature = "jiff02")]
551 if shape.is_type::<jiff::Timestamp>() {
552 use jiff::Timestamp;
553 let ts = value.get::<Timestamp>().map_err(|e| {
554 SerializeError::Custom(alloc::format!("Failed to get Timestamp: {}", e))
555 })?;
556 self.write_str(&ts.to_string())?;
557 return Ok(true);
558 }
559 #[cfg(feature = "jiff02")]
560 if shape.is_type::<jiff::civil::DateTime>() {
561 use jiff::civil::DateTime;
562 let dt = value.get::<DateTime>().map_err(|e| {
563 SerializeError::Custom(alloc::format!("Failed to get DateTime: {}", e))
564 })?;
565 self.write_str(&dt.to_string())?;
566 return Ok(true);
567 }
568
569 #[cfg(feature = "chrono")]
571 if shape.is_type::<chrono::DateTime<chrono::Utc>>() {
572 use chrono::{DateTime, SecondsFormat, Utc};
573 let dt = value.get::<DateTime<Utc>>().map_err(|e| {
574 SerializeError::Custom(alloc::format!("Failed to get DateTime<Utc>: {}", e))
575 })?;
576 self.write_str(&dt.to_rfc3339_opts(SecondsFormat::AutoSi, true))?;
577 return Ok(true);
578 }
579 #[cfg(feature = "chrono")]
580 if shape.is_type::<chrono::DateTime<chrono::Local>>() {
581 use chrono::{DateTime, Local, SecondsFormat};
582 let dt = value.get::<DateTime<Local>>().map_err(|e| {
583 SerializeError::Custom(alloc::format!("Failed to get DateTime<Local>: {}", e))
584 })?;
585 self.write_str(&dt.to_rfc3339_opts(SecondsFormat::AutoSi, false))?;
586 return Ok(true);
587 }
588 #[cfg(feature = "chrono")]
589 if shape.is_type::<chrono::DateTime<chrono::FixedOffset>>() {
590 use chrono::{DateTime, FixedOffset, SecondsFormat};
591 let dt = value.get::<DateTime<FixedOffset>>().map_err(|e| {
592 SerializeError::Custom(alloc::format!("Failed to get DateTime<FixedOffset>: {}", e))
593 })?;
594 self.write_str(&dt.to_rfc3339_opts(SecondsFormat::AutoSi, false))?;
595 return Ok(true);
596 }
597 #[cfg(feature = "chrono")]
598 if shape.is_type::<chrono::NaiveDateTime>() {
599 use chrono::NaiveDateTime;
600 let dt = value.get::<NaiveDateTime>().map_err(|e| {
601 SerializeError::Custom(alloc::format!("Failed to get NaiveDateTime: {}", e))
602 })?;
603 self.write_str(&dt.format("%Y-%m-%dT%H:%M:%S").to_string())?;
604 return Ok(true);
605 }
606 #[cfg(feature = "chrono")]
607 if shape.is_type::<chrono::NaiveDate>() {
608 use chrono::NaiveDate;
609 let date = value.get::<NaiveDate>().map_err(|e| {
610 SerializeError::Custom(alloc::format!("Failed to get NaiveDate: {}", e))
611 })?;
612 self.write_str(&date.to_string())?;
613 return Ok(true);
614 }
615 #[cfg(feature = "chrono")]
616 if shape.is_type::<chrono::NaiveTime>() {
617 use chrono::NaiveTime;
618 let time = value.get::<NaiveTime>().map_err(|e| {
619 SerializeError::Custom(alloc::format!("Failed to get NaiveTime: {}", e))
620 })?;
621 self.write_str(&time.to_string())?;
622 return Ok(true);
623 }
624
625 #[cfg(feature = "time")]
627 if shape.is_type::<time::UtcDateTime>() {
628 use time::UtcDateTime;
629 let dt = value.get::<UtcDateTime>().map_err(|e| {
630 SerializeError::Custom(alloc::format!("Failed to get UtcDateTime: {}", e))
631 })?;
632 let s = dt
633 .format(&time::format_description::well_known::Rfc3339)
634 .unwrap_or_else(|_| "<invalid>".to_string());
635 self.write_str(&s)?;
636 return Ok(true);
637 }
638 #[cfg(feature = "time")]
639 if shape.is_type::<time::OffsetDateTime>() {
640 use time::OffsetDateTime;
641 let dt = value.get::<OffsetDateTime>().map_err(|e| {
642 SerializeError::Custom(alloc::format!("Failed to get OffsetDateTime: {}", e))
643 })?;
644 let s = dt
645 .format(&time::format_description::well_known::Rfc3339)
646 .unwrap_or_else(|_| "<invalid>".to_string());
647 self.write_str(&s)?;
648 return Ok(true);
649 }
650
651 #[cfg(feature = "ordered-float")]
653 if shape.is_type::<ordered_float::OrderedFloat<f32>>() {
654 use ordered_float::OrderedFloat;
655 let val = value.get::<OrderedFloat<f32>>().map_err(|e| {
656 SerializeError::Custom(alloc::format!("Failed to get OrderedFloat<f32>: {}", e))
657 })?;
658 self.writer.write_bytes(&val.0.to_le_bytes())?;
659 return Ok(true);
660 } else if shape.is_type::<ordered_float::OrderedFloat<f64>>() {
661 use ordered_float::OrderedFloat;
662 let val = value.get::<OrderedFloat<f64>>().map_err(|e| {
663 SerializeError::Custom(alloc::format!("Failed to get OrderedFloat<f64>: {}", e))
664 })?;
665 self.writer.write_bytes(&val.0.to_le_bytes())?;
666 return Ok(true);
667 }
668
669 #[cfg(feature = "ordered-float")]
671 if shape.is_type::<ordered_float::NotNan<f32>>() {
672 use ordered_float::NotNan;
673 let val = value.get::<NotNan<f32>>().map_err(|e| {
674 SerializeError::Custom(alloc::format!("Failed to get NotNan<f32>: {}", e))
675 })?;
676 self.writer.write_bytes(&val.into_inner().to_le_bytes())?;
677 return Ok(true);
678 } else if shape.is_type::<ordered_float::NotNan<f64>>() {
679 use ordered_float::NotNan;
680 let val = value.get::<NotNan<f64>>().map_err(|e| {
681 SerializeError::Custom(alloc::format!("Failed to get NotNan<f64>: {}", e))
682 })?;
683 self.writer.write_bytes(&val.into_inner().to_le_bytes())?;
684 return Ok(true);
685 }
686
687 #[cfg(feature = "bytestring")]
689 if shape == <bytestring::ByteString as facet_core::Facet>::SHAPE {
690 let bs = value.get::<bytestring::ByteString>().map_err(|e| {
691 SerializeError::Custom(alloc::format!("Failed to get ByteString: {}", e))
692 })?;
693 self.write_str(bs.as_ref())?;
694 return Ok(true);
695 }
696
697 #[cfg(feature = "compact_str")]
699 if shape == <compact_str::CompactString as facet_core::Facet>::SHAPE {
700 let cs = value.get::<compact_str::CompactString>().map_err(|e| {
701 SerializeError::Custom(alloc::format!("Failed to get CompactString: {}", e))
702 })?;
703 self.write_str(cs.as_str())?;
704 return Ok(true);
705 }
706
707 #[cfg(feature = "smartstring")]
709 if shape == <smartstring::SmartString<smartstring::LazyCompact> as facet_core::Facet>::SHAPE
710 {
711 let ss = value
712 .get::<smartstring::SmartString<smartstring::LazyCompact>>()
713 .map_err(|e| {
714 SerializeError::Custom(alloc::format!("Failed to get SmartString: {}", e))
715 })?;
716 self.write_str(ss.as_str())?;
717 return Ok(true);
718 }
719
720 if shape.inner.is_some() {
721 return Ok(false);
722 }
723
724 if matches!(shape.def, Def::Scalar) {
726 if let Some(s) = value.as_str() {
727 self.write_str(s)?;
728 return Ok(true);
729 }
730 if shape.vtable.has_display() {
731 let s = alloc::format!("{}", value);
732 self.write_str(&s)?;
733 return Ok(true);
734 }
735 }
736
737 Ok(false)
738 }
739}
740
741fn write_varint<W: Writer>(mut value: u64, writer: &mut W) -> Result<(), SerializeError> {
743 loop {
744 let mut byte = (value & 0x7F) as u8;
745 value >>= 7;
746 if value != 0 {
747 byte |= 0x80;
748 }
749 writer.write_byte(byte)?;
750 if value == 0 {
751 break;
752 }
753 }
754 Ok(())
755}
756
757fn write_varint_u128<W: Writer>(mut value: u128, writer: &mut W) -> Result<(), SerializeError> {
759 loop {
760 let mut byte = (value & 0x7F) as u8;
761 value >>= 7;
762 if value != 0 {
763 byte |= 0x80;
764 }
765 writer.write_byte(byte)?;
766 if value == 0 {
767 break;
768 }
769 }
770 Ok(())
771}
772
773fn write_varint_signed<W: Writer>(value: i64, writer: &mut W) -> Result<(), SerializeError> {
775 let encoded = ((value << 1) ^ (value >> 63)) as u64;
777 write_varint(encoded, writer)
778}
779
780fn write_varint_signed_i128<W: Writer>(value: i128, writer: &mut W) -> Result<(), SerializeError> {
782 let encoded = ((value << 1) ^ (value >> 127)) as u128;
784 write_varint_u128(encoded, writer)
785}
786
787#[cfg(test)]
788mod tests {
789 use super::*;
790 use facet::Facet;
791 use facet_value::{VArray, VBytes, VNumber, VObject, VString, Value};
792 use postcard::to_allocvec as postcard_to_vec;
793 use serde::Serialize;
794
795 #[derive(Facet, Serialize, PartialEq, Debug)]
796 struct SimpleStruct {
797 a: u32,
798 b: alloc::string::String,
799 c: bool,
800 }
801
802 #[test]
803 fn test_simple_struct() {
804 facet_testhelpers::setup();
805
806 let value = SimpleStruct {
807 a: 123,
808 b: "hello".into(),
809 c: true,
810 };
811
812 let facet_bytes = to_vec(&value).unwrap();
813 let postcard_bytes = postcard_to_vec(&value).unwrap();
814
815 assert_eq!(facet_bytes, postcard_bytes);
816 }
817
818 #[test]
819 fn test_u8() {
820 facet_testhelpers::setup();
821
822 #[derive(Facet, Serialize, PartialEq, Debug)]
823 struct U8Struct {
824 value: u8,
825 }
826
827 let value = U8Struct { value: 42 };
828 let facet_bytes = to_vec(&value).unwrap();
829 let postcard_bytes = postcard_to_vec(&value).unwrap();
830 assert_eq!(facet_bytes, postcard_bytes);
831 }
832
833 #[test]
834 fn test_i32() {
835 facet_testhelpers::setup();
836
837 #[derive(Facet, Serialize, PartialEq, Debug)]
838 struct I32Struct {
839 value: i32,
840 }
841
842 let value = I32Struct { value: -100000 };
843 let facet_bytes = to_vec(&value).unwrap();
844 let postcard_bytes = postcard_to_vec(&value).unwrap();
845 assert_eq!(facet_bytes, postcard_bytes);
846 }
847
848 #[test]
849 fn test_string() {
850 facet_testhelpers::setup();
851
852 #[derive(Facet, Serialize, PartialEq, Debug)]
853 struct StringStruct {
854 value: alloc::string::String,
855 }
856
857 let value = StringStruct {
858 value: "hello world".into(),
859 };
860 let facet_bytes = to_vec(&value).unwrap();
861 let postcard_bytes = postcard_to_vec(&value).unwrap();
862 assert_eq!(facet_bytes, postcard_bytes);
863 }
864
865 #[test]
866 fn test_vec() {
867 facet_testhelpers::setup();
868
869 #[derive(Facet, Serialize, PartialEq, Debug)]
870 struct VecStruct {
871 values: Vec<u32>,
872 }
873
874 let value = VecStruct {
875 values: alloc::vec![1, 2, 3, 4, 5],
876 };
877 let facet_bytes = to_vec(&value).unwrap();
878 let postcard_bytes = postcard_to_vec(&value).unwrap();
879 assert_eq!(facet_bytes, postcard_bytes);
880 }
881
882 #[test]
883 fn test_option_some() {
884 facet_testhelpers::setup();
885
886 #[derive(Facet, Serialize, PartialEq, Debug)]
887 struct OptionStruct {
888 value: Option<u32>,
889 }
890
891 let value = OptionStruct { value: Some(42) };
892 let facet_bytes = to_vec(&value).unwrap();
893 let postcard_bytes = postcard_to_vec(&value).unwrap();
894 assert_eq!(facet_bytes, postcard_bytes);
895 }
896
897 #[test]
898 fn test_option_none() {
899 facet_testhelpers::setup();
900
901 #[derive(Facet, Serialize, PartialEq, Debug)]
902 struct OptionStruct {
903 value: Option<u32>,
904 }
905
906 let value = OptionStruct { value: None };
907 let facet_bytes = to_vec(&value).unwrap();
908 let postcard_bytes = postcard_to_vec(&value).unwrap();
909 assert_eq!(facet_bytes, postcard_bytes);
910 }
911
912 #[test]
913 fn test_unit_enum() {
914 facet_testhelpers::setup();
915
916 #[derive(Facet, Serialize, PartialEq, Debug)]
917 #[repr(C)]
918 enum Color {
919 Red,
920 Green,
921 Blue,
922 }
923
924 let facet_bytes = to_vec(&Color::Red).unwrap();
925 let postcard_bytes = postcard_to_vec(&Color::Red).unwrap();
926 assert_eq!(facet_bytes, postcard_bytes);
927
928 let facet_bytes = to_vec(&Color::Green).unwrap();
929 let postcard_bytes = postcard_to_vec(&Color::Green).unwrap();
930 assert_eq!(facet_bytes, postcard_bytes);
931
932 let facet_bytes = to_vec(&Color::Blue).unwrap();
933 let postcard_bytes = postcard_to_vec(&Color::Blue).unwrap();
934 assert_eq!(facet_bytes, postcard_bytes);
935 }
936
937 #[test]
938 fn test_tuple_enum() {
939 facet_testhelpers::setup();
940
941 #[derive(Facet, Serialize, PartialEq, Debug)]
942 #[repr(C)]
943 enum Value {
944 Int(i32),
945 Text(alloc::string::String),
946 }
947
948 let facet_bytes = to_vec(&Value::Int(42)).unwrap();
949 let postcard_bytes = postcard_to_vec(&Value::Int(42)).unwrap();
950 assert_eq!(facet_bytes, postcard_bytes);
951
952 let facet_bytes = to_vec(&Value::Text("hello".into())).unwrap();
953 let postcard_bytes = postcard_to_vec(&Value::Text("hello".into())).unwrap();
954 assert_eq!(facet_bytes, postcard_bytes);
955 }
956
957 #[test]
958 fn test_struct_enum() {
959 facet_testhelpers::setup();
960
961 #[derive(Facet, Serialize, PartialEq, Debug)]
962 #[repr(C)]
963 enum Message {
964 Quit,
965 Move { x: i32, y: i32 },
966 }
967
968 let facet_bytes = to_vec(&Message::Quit).unwrap();
969 let postcard_bytes = postcard_to_vec(&Message::Quit).unwrap();
970 assert_eq!(facet_bytes, postcard_bytes);
971
972 let facet_bytes = to_vec(&Message::Move { x: 10, y: 20 }).unwrap();
973 let postcard_bytes = postcard_to_vec(&Message::Move { x: 10, y: 20 }).unwrap();
974 assert_eq!(facet_bytes, postcard_bytes);
975 }
976
977 #[test]
978 fn test_to_writer_fallible() {
979 facet_testhelpers::setup();
980
981 struct CustomWriter {
982 buffer: Vec<u8>,
983 }
984
985 impl Writer for CustomWriter {
986 fn write_byte(&mut self, byte: u8) -> Result<(), SerializeError> {
987 self.buffer.push(byte);
988 Ok(())
989 }
990
991 fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError> {
992 self.buffer.extend_from_slice(bytes);
993 Ok(())
994 }
995 }
996
997 let value = SimpleStruct {
998 a: 123,
999 b: "hello".into(),
1000 c: true,
1001 };
1002
1003 let mut writer = CustomWriter { buffer: Vec::new() };
1004 to_writer_fallible(&value, &mut writer).unwrap();
1005
1006 let postcard_bytes = postcard_to_vec(&value).unwrap();
1007 assert_eq!(writer.buffer, postcard_bytes);
1008 }
1009
1010 #[test]
1011 fn test_value_roundtrip() {
1012 facet_testhelpers::setup();
1013
1014 let mut array = VArray::new();
1015 array.push(Value::from(VNumber::from_i64(1)));
1016 array.push(Value::from(VString::new("two")));
1017 array.push(Value::TRUE);
1018
1019 let mut object = VObject::new();
1020 object.insert("n", Value::from(VNumber::from_u64(42)));
1021 object.insert("s", Value::from(VString::new("hello")));
1022 object.insert("b", Value::from(VBytes::new(&[1, 2, 3])));
1023 object.insert("a", Value::from(array));
1024
1025 let value = Value::from(object);
1026 let bytes = to_vec(&value).unwrap();
1027 let decoded: Value = crate::from_slice(&bytes).unwrap();
1028
1029 assert_eq!(decoded, value);
1030 }
1031}