1#![cfg_attr(not(feature = "std"), no_std)]
2#![warn(missing_docs)]
3#![warn(clippy::std_instead_of_core)]
4#![warn(clippy::std_instead_of_alloc)]
5#![forbid(unsafe_code)]
6#![doc = include_str!("../README.md")]
7
8extern crate alloc;
9
10use alloc::string::String;
11use alloc::vec::Vec;
12
13use facet_core::{Def, Facet, Field, PointerType, ShapeAttribute, StructKind, Type, UserType};
14use facet_reflect::{
15 FieldIter, FieldsForSerializeIter, HasFields, Peek, PeekListLikeIter, PeekMapIter, PeekSetIter,
16 ScalarType,
17};
18use log::{debug, trace};
19
20fn variant_is_newtype_like(variant: &facet_core::Variant) -> bool {
21 variant.data.kind == facet_core::StructKind::Tuple && variant.data.fields.len() == 1
22}
23
24pub trait Serializer<'shape> {
29 type Error;
31
32 fn serialize_u64(&mut self, value: u64) -> Result<(), Self::Error>;
34
35 fn serialize_u128(&mut self, value: u128) -> Result<(), Self::Error>;
37
38 fn serialize_i64(&mut self, value: i64) -> Result<(), Self::Error>;
40
41 fn serialize_i128(&mut self, value: i128) -> Result<(), Self::Error>;
43
44 fn serialize_f64(&mut self, value: f64) -> Result<(), Self::Error>;
46
47 fn serialize_bool(&mut self, value: bool) -> Result<(), Self::Error>;
49
50 fn serialize_char(&mut self, value: char) -> Result<(), Self::Error>;
52
53 fn serialize_str(&mut self, value: &str) -> Result<(), Self::Error>;
55
56 fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error>;
58
59 fn serialize_none(&mut self) -> Result<(), Self::Error>;
63
64 fn serialize_unit(&mut self) -> Result<(), Self::Error>;
66
67 fn serialize_unit_variant(
76 &mut self,
77 variant_index: usize,
78 variant_name: &'shape str,
79 ) -> Result<(), Self::Error>;
80
81 fn start_object(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
87
88 fn serialize_field_name(&mut self, name: &'shape str) -> Result<(), Self::Error>;
94
95 fn start_array(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
101
102 fn start_map(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
108
109 #[inline(always)]
111 fn serialize_u8(&mut self, value: u8) -> Result<(), Self::Error> {
112 self.serialize_u64(value as u64)
113 }
114
115 #[inline(always)]
117 fn serialize_u16(&mut self, value: u16) -> Result<(), Self::Error> {
118 self.serialize_u64(value as u64)
119 }
120
121 #[inline(always)]
123 fn serialize_u32(&mut self, value: u32) -> Result<(), Self::Error> {
124 self.serialize_u64(value as u64)
125 }
126
127 #[inline(always)]
129 fn serialize_usize(&mut self, value: usize) -> Result<(), Self::Error> {
130 self.serialize_u64(value as u64)
132 }
133
134 #[inline(always)]
136 fn serialize_i8(&mut self, value: i8) -> Result<(), Self::Error> {
137 self.serialize_i64(value as i64)
138 }
139
140 #[inline(always)]
142 fn serialize_i16(&mut self, value: i16) -> Result<(), Self::Error> {
143 self.serialize_i64(value as i64)
144 }
145
146 #[inline(always)]
148 fn serialize_i32(&mut self, value: i32) -> Result<(), Self::Error> {
149 self.serialize_i64(value as i64)
150 }
151
152 #[inline(always)]
154 fn serialize_isize(&mut self, value: isize) -> Result<(), Self::Error> {
155 self.serialize_i64(value as i64)
157 }
158
159 #[inline(always)]
161 fn serialize_f32(&mut self, value: f32) -> Result<(), Self::Error> {
162 self.serialize_f64(value as f64)
163 }
164
165 #[inline(always)]
167 fn begin_map_key(&mut self) -> Result<(), Self::Error> {
168 Ok(())
169 }
170
171 #[inline(always)]
173 fn end_map_key(&mut self) -> Result<(), Self::Error> {
174 Ok(())
175 }
176
177 #[inline(always)]
179 fn begin_map_value(&mut self) -> Result<(), Self::Error> {
180 Ok(())
181 }
182
183 #[inline(always)]
185 fn end_map_value(&mut self) -> Result<(), Self::Error> {
186 Ok(())
187 }
188
189 #[inline(always)]
191 fn end_object(&mut self) -> Result<(), Self::Error> {
192 Ok(())
193 }
194
195 #[inline(always)]
197 fn end_array(&mut self) -> Result<(), Self::Error> {
198 Ok(())
199 }
200
201 #[inline(always)]
203 fn end_map(&mut self) -> Result<(), Self::Error> {
204 Ok(())
205 }
206
207 #[inline(always)]
209 fn end_field(&mut self) -> Result<(), Self::Error> {
210 Ok(())
211 }
212
213 #[inline(always)]
215 fn start_enum_variant(&mut self, discriminant: u64) -> Result<(), Self::Error> {
216 let _ = discriminant;
217 Ok(())
218 }
219}
220
221enum SerializeTask<'mem, 'facet, 'shape> {
225 Value(Peek<'mem, 'facet, 'shape>, Option<Field<'shape>>),
226 Object {
227 entries: FieldsForSerializeIter<'mem, 'facet, 'shape>,
228 first: bool,
229 len: usize,
230 },
231 Array {
232 items: PeekListLikeIter<'mem, 'facet, 'shape>,
233 first: bool,
234 },
235 Set {
236 items: PeekSetIter<'mem, 'facet, 'shape>,
237 first: bool,
238 len: usize,
239 },
240 Map {
241 entries: PeekMapIter<'mem, 'facet, 'shape>,
242 first: bool,
243 len: usize,
244 },
245 TupleStruct {
246 items: FieldsForSerializeIter<'mem, 'facet, 'shape>,
247 first: bool,
248 len: usize,
249 },
250 Tuple {
251 items: FieldIter<'mem, 'facet, 'shape>,
252 first: bool,
253 },
254 EndObject,
256 EndArray,
257 EndMapKey,
258 EndMapValue,
259 EndField,
260 SerializeFieldName(&'shape str),
262 SerializeMapKey(Peek<'mem, 'facet, 'shape>),
263 SerializeMapValue(Peek<'mem, 'facet, 'shape>),
264}
265
266pub fn serialize_iterative<'mem, 'facet, 'shape, S>(
270 peek: Peek<'mem, 'facet, 'shape>,
271 serializer: &mut S,
272) -> Result<(), S::Error>
273where
274 S: Serializer<'shape>,
275{
276 let mut stack = Vec::new();
277 stack.push(SerializeTask::Value(peek, None));
278
279 while let Some(task) = stack.pop() {
280 match task {
281 SerializeTask::Value(mut cpeek, maybe_field) => {
282 debug!("Serializing a value, shape is {}", cpeek.shape());
283
284 if cpeek
285 .shape()
286 .attributes
287 .contains(&ShapeAttribute::Transparent)
288 {
289 let old_shape = cpeek.shape();
290
291 let ps = cpeek.into_struct().unwrap();
293 cpeek = ps.field(0).unwrap();
294
295 let new_shape = cpeek.shape();
296 debug!(
297 "{old_shape} is transparent, let's serialize the inner {new_shape} instead"
298 );
299 }
300
301 debug!(
302 "Matching def={:?}, ty={:?} for shape={}",
303 cpeek.shape().def,
304 cpeek.shape().ty,
305 cpeek.shape()
306 );
307 match (cpeek.shape().def, cpeek.shape().ty) {
308 (Def::Scalar, _) => {
309 let cpeek = cpeek.innermost_peek();
310
311 match cpeek.scalar_type() {
313 Some(ScalarType::Unit) => serializer.serialize_unit()?,
314 Some(ScalarType::Bool) => {
315 serializer.serialize_bool(*cpeek.get::<bool>().unwrap())?
316 }
317 Some(ScalarType::Char) => {
318 serializer.serialize_char(*cpeek.get::<char>().unwrap())?
319 }
320
321 Some(ScalarType::Str) => {
323 serializer.serialize_str(cpeek.get::<str>().unwrap())?
324 }
325 Some(ScalarType::String) => {
326 serializer.serialize_str(cpeek.get::<String>().unwrap())?
327 }
328 Some(ScalarType::CowStr) => serializer.serialize_str(
329 cpeek.get::<alloc::borrow::Cow<'_, str>>().unwrap().as_ref(),
330 )?,
331
332 Some(ScalarType::F32) => {
334 serializer.serialize_f32(*cpeek.get::<f32>().unwrap())?
335 }
336 Some(ScalarType::F64) => {
337 serializer.serialize_f64(*cpeek.get::<f64>().unwrap())?
338 }
339
340 Some(ScalarType::U8) => {
342 serializer.serialize_u8(*cpeek.get::<u8>().unwrap())?
343 }
344 Some(ScalarType::U16) => {
345 serializer.serialize_u16(*cpeek.get::<u16>().unwrap())?
346 }
347 Some(ScalarType::U32) => {
348 serializer.serialize_u32(*cpeek.get::<u32>().unwrap())?
349 }
350 Some(ScalarType::U64) => {
351 serializer.serialize_u64(*cpeek.get::<u64>().unwrap())?
352 }
353 Some(ScalarType::U128) => {
354 serializer.serialize_u128(*cpeek.get::<u128>().unwrap())?
355 }
356 Some(ScalarType::USize) => {
357 serializer.serialize_usize(*cpeek.get::<usize>().unwrap())?
358 }
359 Some(ScalarType::I8) => {
360 serializer.serialize_i8(*cpeek.get::<i8>().unwrap())?
361 }
362 Some(ScalarType::I16) => {
363 serializer.serialize_i16(*cpeek.get::<i16>().unwrap())?
364 }
365 Some(ScalarType::I32) => {
366 serializer.serialize_i32(*cpeek.get::<i32>().unwrap())?
367 }
368 Some(ScalarType::I64) => {
369 serializer.serialize_i64(*cpeek.get::<i64>().unwrap())?
370 }
371 Some(ScalarType::I128) => {
372 serializer.serialize_i128(*cpeek.get::<i128>().unwrap())?
373 }
374 Some(ScalarType::ISize) => {
375 serializer.serialize_isize(*cpeek.get::<isize>().unwrap())?
376 }
377 Some(unsupported) => {
378 panic!("facet-serialize: unsupported scalar type: {unsupported:?}")
379 }
380 None => {
381 if let Some(_display) =
384 cpeek.shape().vtable.sized().and_then(|v| (v.display)())
385 {
386 serializer.serialize_str(&alloc::format!("{cpeek}"))?
388 } else {
389 panic!("Unsupported shape (no display): {}", cpeek.shape())
390 }
391 }
392 }
393 }
394 (Def::List(ld), _) => {
395 if ld.t().is_type::<u8>() {
396 if cpeek.shape().is_type::<Vec<u8>>() {
398 serializer.serialize_bytes(cpeek.get::<Vec<u8>>().unwrap())?
399 } else {
400 let peek_list = cpeek.into_list_like().unwrap();
403 stack.push(SerializeTask::Array {
404 items: peek_list.iter(),
405 first: true,
406 });
407 }
408 } else {
409 let peek_list = cpeek.into_list_like().unwrap();
410 stack.push(SerializeTask::Array {
411 items: peek_list.iter(),
412 first: true,
413 });
414 }
415 }
416 (Def::Array(ad), _) => {
417 if ad.t().is_type::<u8>() {
418 let bytes: Vec<u8> = cpeek
419 .into_list_like()
420 .unwrap()
421 .iter()
422 .map(|p| *p.get::<u8>().unwrap())
423 .collect();
424 serializer.serialize_bytes(&bytes)?;
425 } else {
426 let peek_list = cpeek.into_list_like().unwrap();
427 stack.push(SerializeTask::Array {
428 items: peek_list.iter(),
429 first: true,
430 });
431 }
432 }
433 (Def::Slice(sd), _) => {
434 if sd.t().is_type::<u8>() {
435 serializer.serialize_bytes(cpeek.get::<[u8]>().unwrap())?
436 } else {
437 let peek_list = cpeek.into_list_like().unwrap();
438 stack.push(SerializeTask::Array {
439 items: peek_list.iter(),
440 first: true,
441 });
442 }
443 }
444 (Def::Map(_), _) => {
445 let peek_map = cpeek.into_map().unwrap();
446 let len = peek_map.len();
447 stack.push(SerializeTask::Map {
448 entries: peek_map.iter(),
449 first: true,
450 len,
451 });
452 }
453 (Def::Set(_), _) => {
454 let peek_set = cpeek.into_set().unwrap();
455 stack.push(SerializeTask::Set {
456 items: peek_set.iter(),
457 first: true,
458 len: peek_set.len(),
459 });
460 }
461 (Def::Option(_), _) => {
462 let opt = cpeek.into_option().unwrap();
463 if let Some(inner_peek) = opt.value() {
464 stack.push(SerializeTask::Value(inner_peek, None));
465 } else {
466 serializer.serialize_none()?;
467 }
468 }
469 (Def::Pointer(_), _) => {
470 let sp = cpeek.into_pointer().unwrap();
474 if let Some(inner_peek) = sp.borrow_inner() {
475 stack.push(SerializeTask::Value(inner_peek, None));
477 } else {
478 todo!(
481 "Smart pointer without borrow support or with opaque pointee cannot be serialized"
482 );
483 }
484 }
485 (_, Type::User(UserType::Struct(sd))) => {
486 debug!("Serializing struct: shape={}", cpeek.shape(),);
487 debug!(
488 " Struct details: kind={:?}, field_count={}",
489 sd.kind,
490 sd.fields.len()
491 );
492
493 match sd.kind {
494 StructKind::Unit => {
495 debug!(" Handling unit struct (no fields)");
496 serializer.serialize_unit()?;
498 }
499 StructKind::Tuple => {
500 debug!(" Handling tuple with {} fields", sd.fields.len());
501 let peek_struct = cpeek.into_struct().unwrap();
502 let fields_iter = peek_struct.fields();
503 debug!(" Serializing {} fields as tuple", sd.fields.len());
504
505 stack.push(SerializeTask::Tuple {
506 items: fields_iter,
507 first: true,
508 });
509 trace!(
510 " Pushed TupleFields to stack for tuple, will handle {} fields",
511 sd.fields.len()
512 );
513 }
514 StructKind::TupleStruct => {
515 debug!(" Handling tuple struct");
516 let peek_struct = cpeek.into_struct().unwrap();
517 let fields = peek_struct.fields_for_serialize().count();
518 debug!(" Serializing {fields} fields as array");
519
520 stack.push(SerializeTask::TupleStruct {
521 items: peek_struct.fields_for_serialize(),
522 first: true,
523 len: fields,
524 });
525 trace!(
526 " Pushed TupleStructFields to stack, will handle {fields} fields"
527 );
528 }
529 StructKind::Struct => {
530 debug!(" Handling record struct");
531 let peek_struct = cpeek.into_struct().unwrap();
532 let fields = peek_struct.fields_for_serialize().count();
533 debug!(" Serializing {fields} fields as object");
534
535 stack.push(SerializeTask::Object {
536 entries: peek_struct.fields_for_serialize(),
537 first: true,
538 len: fields,
539 });
540 trace!(
541 " Pushed ObjectFields to stack, will handle {fields} fields"
542 );
543 }
544 }
545 }
546 (_, Type::User(UserType::Enum(_))) => {
547 let peek_enum = cpeek.into_enum().unwrap();
548 let variant = peek_enum
549 .active_variant()
550 .expect("Failed to get active variant");
551 let variant_index = peek_enum
552 .variant_index()
553 .expect("Failed to get variant index");
554 trace!("Active variant index is {variant_index}, variant is {variant:?}");
555 let discriminant = variant
556 .discriminant
557 .map(|d| d as u64)
558 .unwrap_or(variant_index as u64);
559 serializer.start_enum_variant(discriminant)?;
560 let flattened = maybe_field.map(|f| f.flattened).unwrap_or_default();
561
562 if variant.data.fields.is_empty() {
563 serializer.serialize_unit_variant(variant_index, variant.name)?;
565 } else {
566 if !flattened {
567 serializer.start_object(Some(1))?;
569 stack.push(SerializeTask::EndObject);
570
571 serializer.serialize_field_name(variant.name)?;
573 }
574
575 if variant_is_newtype_like(variant) {
576 let fields = peek_enum.fields_for_serialize().collect::<Vec<_>>();
578 let (field, field_peek) = fields[0];
579 stack.push(SerializeTask::Value(field_peek, Some(field)));
581 } else if variant.data.kind == StructKind::Tuple
582 || variant.data.kind == StructKind::TupleStruct
583 {
584 let fields = peek_enum.fields_for_serialize().count();
586 serializer.start_array(Some(fields))?;
587 stack.push(SerializeTask::EndArray);
588
589 let fields_for_serialize =
591 peek_enum.fields_for_serialize().collect::<Vec<_>>();
592 for (field, field_peek) in fields_for_serialize.into_iter().rev() {
593 stack.push(SerializeTask::Value(field_peek, Some(field)));
594 }
595 } else {
596 let fields = peek_enum.fields_for_serialize().count();
598 serializer.start_object(Some(fields))?;
599 stack.push(SerializeTask::EndObject);
600
601 let fields_for_serialize =
603 peek_enum.fields_for_serialize().collect::<Vec<_>>();
604 for (field, field_peek) in fields_for_serialize.into_iter().rev() {
605 stack.push(SerializeTask::EndField);
606 stack.push(SerializeTask::Value(field_peek, Some(field)));
607 stack.push(SerializeTask::SerializeFieldName(field.name));
608 }
609 }
610 }
611 }
612 (_, Type::Pointer(pointer_type)) => {
613 if let Some(str_value) = cpeek.as_str() {
615 serializer.serialize_str(str_value)?;
617 } else if let Some(bytes) = cpeek.as_bytes() {
618 serializer.serialize_bytes(bytes)?;
620 } else if let PointerType::Function(_) = pointer_type {
621 serializer.serialize_unit()?;
623 } else {
624 let innermost = cpeek.innermost_peek();
626 if innermost.shape() != cpeek.shape() {
627 stack.push(SerializeTask::Value(innermost, None));
629 } else {
630 serializer.serialize_unit()?;
632 }
633 }
634 }
635 _ => {
636 debug!(
638 "Unhandled type: {:?}, falling back to unit",
639 cpeek.shape().ty
640 );
641 serializer.serialize_unit()?;
642 }
643 }
644 }
645
646 SerializeTask::Object {
647 mut entries,
648 first,
649 len,
650 } => {
651 if first {
652 serializer.start_object(Some(len))?;
653 }
654
655 let Some((field, value)) = entries.next() else {
656 serializer.end_object()?;
657 continue;
658 };
659
660 stack.push(SerializeTask::Object {
661 entries,
662 first: false,
663 len,
664 });
665 stack.push(SerializeTask::EndField);
666 stack.push(SerializeTask::Value(value, Some(field)));
667 stack.push(SerializeTask::SerializeFieldName(field.name));
668 }
669 SerializeTask::Array { mut items, first } => {
670 if first {
671 serializer.start_array(Some(items.len()))?;
672 }
673
674 let Some(value) = items.next() else {
675 serializer.end_array()?;
676 continue;
677 };
678
679 stack.push(SerializeTask::Array {
680 items,
681 first: false,
682 });
683 stack.push(SerializeTask::Value(value, None));
684 }
685 SerializeTask::Set {
686 mut items,
687 first,
688 len,
689 } => {
690 if first {
691 serializer.start_array(Some(len))?;
692 }
693
694 let Some(value) = items.next() else {
695 serializer.end_array()?;
696 continue;
697 };
698
699 stack.push(SerializeTask::Set {
700 items,
701 first: false,
702 len,
703 });
704 stack.push(SerializeTask::Value(value, None));
705 }
706 SerializeTask::Map {
707 mut entries,
708 first,
709 len,
710 } => {
711 if first {
712 serializer.start_map(Some(len))?;
713 }
714
715 let Some((key, value)) = entries.next() else {
716 serializer.end_map()?;
717 continue;
718 };
719
720 stack.push(SerializeTask::Map {
721 entries,
722 first: false,
723 len,
724 });
725 stack.push(SerializeTask::SerializeMapValue(value));
726 stack.push(SerializeTask::SerializeMapKey(key));
727 }
728 SerializeTask::TupleStruct {
729 mut items,
730 first,
731 len,
732 } => {
733 if first {
734 serializer.start_array(Some(len))?;
735 }
736
737 let Some((field, value)) = items.next() else {
738 serializer.end_array()?;
739 continue;
740 };
741
742 stack.push(SerializeTask::TupleStruct {
743 items,
744 first: false,
745 len,
746 });
747 stack.push(SerializeTask::Value(value, Some(field)));
748 }
749 SerializeTask::Tuple { mut items, first } => {
750 if first {
751 serializer.start_array(Some(items.len()))?;
752 }
753
754 let Some((field, value)) = items.next() else {
755 serializer.end_array()?;
756 continue;
757 };
758
759 stack.push(SerializeTask::Tuple {
760 items,
761 first: false,
762 });
763 stack.push(SerializeTask::Value(value, Some(field)));
764 }
765
766 SerializeTask::SerializeFieldName(name) => {
768 serializer.serialize_field_name(name)?;
769 }
770 SerializeTask::SerializeMapKey(key_peek) => {
771 stack.push(SerializeTask::EndMapKey);
772 stack.push(SerializeTask::Value(key_peek, None));
773 serializer.begin_map_key()?;
774 }
775 SerializeTask::SerializeMapValue(value_peek) => {
776 stack.push(SerializeTask::EndMapValue);
777 stack.push(SerializeTask::Value(value_peek, None));
778 serializer.begin_map_value()?;
779 }
780
781 SerializeTask::EndObject => {
783 serializer.end_object()?;
784 }
785 SerializeTask::EndArray => {
786 serializer.end_array()?;
787 }
788 SerializeTask::EndMapKey => {
789 serializer.end_map_key()?;
790 }
791 SerializeTask::EndMapValue => {
792 serializer.end_map_value()?;
793 }
794 SerializeTask::EndField => {
795 serializer.end_field()?;
796 }
797 }
798 }
799
800 Ok(())
802}
803
804pub trait Serialize<'a>: Facet<'a> {
808 fn serialize<'shape, S: Serializer<'shape>>(
810 &'a self,
811 serializer: &mut S,
812 ) -> Result<(), S::Error>;
813}
814
815impl<'a, T> Serialize<'a> for T
816where
817 T: Facet<'a>,
818{
819 fn serialize<'shape, S: Serializer<'shape>>(
821 &'a self,
822 serializer: &mut S,
823 ) -> Result<(), S::Error> {
824 let peek = Peek::new(self);
825 serialize_iterative(peek, serializer)
826 }
827}