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::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 {
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 start_some(&mut self) -> Result<(), Self::Error> {
66 Ok(())
67 }
68
69 fn serialize_unit(&mut self) -> Result<(), Self::Error>;
71
72 fn serialize_unit_variant(
81 &mut self,
82 variant_index: usize,
83 variant_name: &'static str,
84 ) -> Result<(), Self::Error>;
85
86 fn start_object(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
92
93 fn serialize_field_name(&mut self, name: &'static str) -> Result<(), Self::Error>;
99
100 fn start_array(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
106
107 fn start_map(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
113
114 #[inline(always)]
116 fn serialize_u8(&mut self, value: u8) -> Result<(), Self::Error> {
117 self.serialize_u64(value as u64)
118 }
119
120 #[inline(always)]
122 fn serialize_u16(&mut self, value: u16) -> Result<(), Self::Error> {
123 self.serialize_u64(value as u64)
124 }
125
126 #[inline(always)]
128 fn serialize_u32(&mut self, value: u32) -> Result<(), Self::Error> {
129 self.serialize_u64(value as u64)
130 }
131
132 #[inline(always)]
134 fn serialize_usize(&mut self, value: usize) -> Result<(), Self::Error> {
135 self.serialize_u64(value as u64)
137 }
138
139 #[inline(always)]
141 fn serialize_i8(&mut self, value: i8) -> Result<(), Self::Error> {
142 self.serialize_i64(value as i64)
143 }
144
145 #[inline(always)]
147 fn serialize_i16(&mut self, value: i16) -> Result<(), Self::Error> {
148 self.serialize_i64(value as i64)
149 }
150
151 #[inline(always)]
153 fn serialize_i32(&mut self, value: i32) -> Result<(), Self::Error> {
154 self.serialize_i64(value as i64)
155 }
156
157 #[inline(always)]
159 fn serialize_isize(&mut self, value: isize) -> Result<(), Self::Error> {
160 self.serialize_i64(value as i64)
162 }
163
164 #[inline(always)]
166 fn serialize_f32(&mut self, value: f32) -> Result<(), Self::Error> {
167 self.serialize_f64(value as f64)
168 }
169
170 #[inline(always)]
172 fn begin_map_key(&mut self) -> Result<(), Self::Error> {
173 Ok(())
174 }
175
176 #[inline(always)]
178 fn end_map_key(&mut self) -> Result<(), Self::Error> {
179 Ok(())
180 }
181
182 #[inline(always)]
184 fn begin_map_value(&mut self) -> Result<(), Self::Error> {
185 Ok(())
186 }
187
188 #[inline(always)]
190 fn end_map_value(&mut self) -> Result<(), Self::Error> {
191 Ok(())
192 }
193
194 #[inline(always)]
196 fn end_object(&mut self) -> Result<(), Self::Error> {
197 Ok(())
198 }
199
200 #[inline(always)]
202 fn end_array(&mut self) -> Result<(), Self::Error> {
203 Ok(())
204 }
205
206 #[inline(always)]
208 fn end_map(&mut self) -> Result<(), Self::Error> {
209 Ok(())
210 }
211
212 #[inline(always)]
214 fn end_field(&mut self) -> Result<(), Self::Error> {
215 Ok(())
216 }
217
218 #[inline(always)]
220 fn start_enum_variant(&mut self, discriminant: u64) -> Result<(), Self::Error> {
221 let _ = discriminant;
222 Ok(())
223 }
224}
225
226enum SerializeTask<'mem, 'facet> {
230 Value(Peek<'mem, 'facet>, Option<Field>),
231 Object {
232 entries: FieldsForSerializeIter<'mem, 'facet>,
233 first: bool,
234 len: usize,
235 },
236 Array {
237 items: PeekListLikeIter<'mem, 'facet>,
238 first: bool,
239 },
240 Set {
241 items: PeekSetIter<'mem, 'facet>,
242 first: bool,
243 len: usize,
244 },
245 Map {
246 entries: PeekMapIter<'mem, 'facet>,
247 first: bool,
248 len: usize,
249 },
250 TupleStruct {
251 items: FieldsForSerializeIter<'mem, 'facet>,
252 first: bool,
253 len: usize,
254 },
255 Tuple {
256 items: FieldIter<'mem, 'facet>,
257 first: bool,
258 },
259 EndObject,
261 EndArray,
262 EndMapKey,
263 EndMapValue,
264 EndField,
265 SerializeFieldName(&'static str),
267 SerializeMapKey(Peek<'mem, 'facet>),
268 SerializeMapValue(Peek<'mem, 'facet>),
269}
270
271pub fn serialize_iterative<'mem, 'facet, S>(
275 peek: Peek<'mem, 'facet>,
276 serializer: &mut S,
277) -> Result<(), S::Error>
278where
279 S: Serializer,
280{
281 let mut stack = Vec::new();
282 stack.push(SerializeTask::Value(peek, None));
283
284 while let Some(task) = stack.pop() {
285 match task {
286 SerializeTask::Value(mut cpeek, maybe_field) => {
287 trace!("Serializing a value, shape is {}", cpeek.shape());
288
289 #[cfg(feature = "alloc")]
290 if let Some(f) = maybe_field {
291 if f.vtable.serialize_with.is_some() {
292 let owned_peek = cpeek.custom_serialization(f).unwrap();
293 let old_shape = cpeek.shape();
294 let new_shape = owned_peek.shape();
295 trace!(
296 "{old_shape} has custom serialization, serializing as {new_shape} instead"
297 );
298 serialize_iterative(owned_peek.as_peek(), serializer)?;
302 continue;
303 }
304 }
305
306 if cpeek
307 .shape()
308 .attributes
309 .contains(&ShapeAttribute::Transparent)
310 {
311 let old_shape = cpeek.shape();
312
313 let ps = cpeek.into_struct().unwrap();
315 cpeek = ps.field(0).unwrap();
316
317 let new_shape = cpeek.shape();
318 trace!(
319 "{old_shape} is transparent, let's serialize the inner {new_shape} instead"
320 );
321 }
322
323 trace!(
324 "Matching def={:?}, ty={:?} for shape={}",
325 cpeek.shape().def,
326 cpeek.shape().ty,
327 cpeek.shape()
328 );
329 match (cpeek.shape().def, cpeek.shape().ty) {
330 (Def::Scalar, _) => {
331 let cpeek = cpeek.innermost_peek();
332
333 match cpeek.scalar_type() {
335 Some(ScalarType::Unit) => serializer.serialize_unit()?,
336 Some(ScalarType::Bool) => {
337 serializer.serialize_bool(*cpeek.get::<bool>().unwrap())?
338 }
339 Some(ScalarType::Char) => {
340 serializer.serialize_char(*cpeek.get::<char>().unwrap())?
341 }
342
343 Some(ScalarType::Str) => {
345 serializer.serialize_str(cpeek.get::<str>().unwrap())?
346 }
347 Some(ScalarType::String) => {
348 serializer.serialize_str(cpeek.get::<String>().unwrap())?
349 }
350 Some(ScalarType::CowStr) => serializer.serialize_str(
351 cpeek.get::<alloc::borrow::Cow<'_, str>>().unwrap().as_ref(),
352 )?,
353
354 Some(ScalarType::F32) => {
356 serializer.serialize_f32(*cpeek.get::<f32>().unwrap())?
357 }
358 Some(ScalarType::F64) => {
359 serializer.serialize_f64(*cpeek.get::<f64>().unwrap())?
360 }
361
362 Some(ScalarType::U8) => {
364 serializer.serialize_u8(*cpeek.get::<u8>().unwrap())?
365 }
366 Some(ScalarType::U16) => {
367 serializer.serialize_u16(*cpeek.get::<u16>().unwrap())?
368 }
369 Some(ScalarType::U32) => {
370 serializer.serialize_u32(*cpeek.get::<u32>().unwrap())?
371 }
372 Some(ScalarType::U64) => {
373 serializer.serialize_u64(*cpeek.get::<u64>().unwrap())?
374 }
375 Some(ScalarType::U128) => {
376 serializer.serialize_u128(*cpeek.get::<u128>().unwrap())?
377 }
378 Some(ScalarType::USize) => {
379 serializer.serialize_usize(*cpeek.get::<usize>().unwrap())?
380 }
381 Some(ScalarType::I8) => {
382 serializer.serialize_i8(*cpeek.get::<i8>().unwrap())?
383 }
384 Some(ScalarType::I16) => {
385 serializer.serialize_i16(*cpeek.get::<i16>().unwrap())?
386 }
387 Some(ScalarType::I32) => {
388 serializer.serialize_i32(*cpeek.get::<i32>().unwrap())?
389 }
390 Some(ScalarType::I64) => {
391 serializer.serialize_i64(*cpeek.get::<i64>().unwrap())?
392 }
393 Some(ScalarType::I128) => {
394 serializer.serialize_i128(*cpeek.get::<i128>().unwrap())?
395 }
396 Some(ScalarType::ISize) => {
397 serializer.serialize_isize(*cpeek.get::<isize>().unwrap())?
398 }
399 Some(unsupported) => {
400 panic!("facet-serialize: unsupported scalar type: {unsupported:?}")
401 }
402 None => {
403 if let Some(_display) = cpeek.shape().vtable.display {
406 serializer.serialize_str(&alloc::format!("{cpeek}"))?
408 } else {
409 panic!("Unsupported shape (no display): {}", cpeek.shape())
410 }
411 }
412 }
413 }
414 (Def::List(ld), _) => {
415 if ld.t().is_type::<u8>() {
416 if cpeek.shape().is_type::<Vec<u8>>() {
418 serializer.serialize_bytes(cpeek.get::<Vec<u8>>().unwrap())?
419 } else {
420 let peek_list = cpeek.into_list_like().unwrap();
423 stack.push(SerializeTask::Array {
424 items: peek_list.iter(),
425 first: true,
426 });
427 }
428 } else {
429 let peek_list = cpeek.into_list_like().unwrap();
430 stack.push(SerializeTask::Array {
431 items: peek_list.iter(),
432 first: true,
433 });
434 }
435 }
436 (Def::Array(ad), _) => {
437 if ad.t().is_type::<u8>() {
438 let bytes: Vec<u8> = cpeek
439 .into_list_like()
440 .unwrap()
441 .iter()
442 .map(|p| *p.get::<u8>().unwrap())
443 .collect();
444 serializer.serialize_bytes(&bytes)?;
445 } else {
446 let peek_list = cpeek.into_list_like().unwrap();
447 stack.push(SerializeTask::Array {
448 items: peek_list.iter(),
449 first: true,
450 });
451 }
452 }
453 (Def::Slice(sd), _) => {
454 if sd.t().is_type::<u8>() {
455 serializer.serialize_bytes(cpeek.get::<[u8]>().unwrap())?
456 } else {
457 let peek_list = cpeek.into_list_like().unwrap();
458 stack.push(SerializeTask::Array {
459 items: peek_list.iter(),
460 first: true,
461 });
462 }
463 }
464 (Def::Map(_), _) => {
465 let peek_map = cpeek.into_map().unwrap();
466 let len = peek_map.len();
467 stack.push(SerializeTask::Map {
468 entries: peek_map.iter(),
469 first: true,
470 len,
471 });
472 }
473 (Def::Set(_), _) => {
474 let peek_set = cpeek.into_set().unwrap();
475 stack.push(SerializeTask::Set {
476 items: peek_set.iter(),
477 first: true,
478 len: peek_set.len(),
479 });
480 }
481 (Def::Option(_), _) => {
482 let opt = cpeek.into_option().unwrap();
483 if let Some(inner_peek) = opt.value() {
484 serializer.start_some()?;
485 stack.push(SerializeTask::Value(inner_peek, None));
486 } else {
487 serializer.serialize_none()?;
488 }
489 }
490 (Def::Pointer(_), _) => {
491 let sp = cpeek.into_pointer().unwrap();
495 if let Some(inner_peek) = sp.borrow_inner() {
496 stack.push(SerializeTask::Value(inner_peek, None));
498 } else {
499 todo!(
502 "Smart pointer without borrow support or with opaque pointee cannot be serialized"
503 );
504 }
505 }
506 (_, Type::User(UserType::Struct(sd))) => {
507 trace!("Serializing struct: shape={}", cpeek.shape(),);
508 trace!(
509 " Struct details: kind={:?}, field_count={}",
510 sd.kind,
511 sd.fields.len()
512 );
513
514 match sd.kind {
515 StructKind::Unit => {
516 trace!(" Handling unit struct (no fields)");
517 serializer.serialize_unit()?;
519 }
520 StructKind::Tuple => {
521 trace!(" Handling tuple with {} fields", sd.fields.len());
522 let peek_struct = cpeek.into_struct().unwrap();
523 let fields_iter = peek_struct.fields();
524 trace!(" Serializing {} fields as tuple", sd.fields.len());
525
526 stack.push(SerializeTask::Tuple {
527 items: fields_iter,
528 first: true,
529 });
530 trace!(
531 " Pushed TupleFields to stack for tuple, will handle {} fields",
532 sd.fields.len()
533 );
534 }
535 StructKind::TupleStruct => {
536 trace!(" Handling tuple struct");
537 let peek_struct = cpeek.into_struct().unwrap();
538 let fields = peek_struct.fields_for_serialize().count();
539 trace!(" Serializing {fields} fields as array");
540
541 stack.push(SerializeTask::TupleStruct {
542 items: peek_struct.fields_for_serialize(),
543 first: true,
544 len: fields,
545 });
546 trace!(
547 " Pushed TupleStructFields to stack, will handle {fields} fields"
548 );
549 }
550 StructKind::Struct => {
551 trace!(" Handling record struct");
552 let peek_struct = cpeek.into_struct().unwrap();
553 let fields = peek_struct.fields_for_serialize().count();
554 trace!(" Serializing {fields} fields as object");
555
556 stack.push(SerializeTask::Object {
557 entries: peek_struct.fields_for_serialize(),
558 first: true,
559 len: fields,
560 });
561 trace!(
562 " Pushed ObjectFields to stack, will handle {fields} fields"
563 );
564 }
565 }
566 }
567 (_, Type::User(UserType::Enum(_))) => {
568 let peek_enum = cpeek.into_enum().unwrap();
569 let variant = peek_enum
570 .active_variant()
571 .expect("Failed to get active variant");
572 let variant_index = peek_enum
573 .variant_index()
574 .expect("Failed to get variant index");
575 trace!("Active variant index is {variant_index}, variant is {variant:?}");
576 let discriminant = variant
577 .discriminant
578 .map(|d| d as u64)
579 .unwrap_or(variant_index as u64);
580 serializer.start_enum_variant(discriminant)?;
581 let flattened = maybe_field.map(|f| f.flattened).unwrap_or_default();
582
583 if variant.data.fields.is_empty() {
584 serializer.serialize_unit_variant(variant_index, variant.name)?;
586 } else {
587 if !flattened {
588 serializer.start_object(Some(1))?;
590 stack.push(SerializeTask::EndObject);
591
592 serializer.serialize_field_name(variant.name)?;
594 }
595
596 if variant_is_newtype_like(variant) {
597 let fields = peek_enum.fields_for_serialize().collect::<Vec<_>>();
599 let (field, field_peek) = fields[0];
600 stack.push(SerializeTask::Value(field_peek, Some(field)));
602 } else if variant.data.kind == StructKind::Tuple
603 || variant.data.kind == StructKind::TupleStruct
604 {
605 let fields = peek_enum.fields_for_serialize().count();
607 serializer.start_array(Some(fields))?;
608 stack.push(SerializeTask::EndArray);
609
610 let fields_for_serialize =
612 peek_enum.fields_for_serialize().collect::<Vec<_>>();
613 for (field, field_peek) in fields_for_serialize.into_iter().rev() {
614 stack.push(SerializeTask::Value(field_peek, Some(field)));
615 }
616 } else {
617 let fields = peek_enum.fields_for_serialize().count();
619 serializer.start_object(Some(fields))?;
620 stack.push(SerializeTask::EndObject);
621
622 let fields_for_serialize =
624 peek_enum.fields_for_serialize().collect::<Vec<_>>();
625 for (field, field_peek) in fields_for_serialize.into_iter().rev() {
626 stack.push(SerializeTask::EndField);
627 stack.push(SerializeTask::Value(field_peek, Some(field)));
628 stack.push(SerializeTask::SerializeFieldName(field.name));
629 }
630 }
631 }
632 }
633 (_, Type::Pointer(pointer_type)) => {
634 if let Some(str_value) = cpeek.as_str() {
636 serializer.serialize_str(str_value)?;
638 } else if let Some(bytes) = cpeek.as_bytes() {
639 serializer.serialize_bytes(bytes)?;
641 } else if let PointerType::Function(_) = pointer_type {
642 serializer.serialize_unit()?;
644 } else {
645 let innermost = cpeek.innermost_peek();
647 if innermost.shape() != cpeek.shape() {
648 stack.push(SerializeTask::Value(innermost, None));
650 } else {
651 serializer.serialize_unit()?;
653 }
654 }
655 }
656 _ => {
657 trace!(
659 "Unhandled type: {:?}, falling back to unit",
660 cpeek.shape().ty
661 );
662 serializer.serialize_unit()?;
663 }
664 }
665 }
666
667 SerializeTask::Object {
668 mut entries,
669 first,
670 len,
671 } => {
672 if first {
673 serializer.start_object(Some(len))?;
674 }
675
676 let Some((field, value)) = entries.next() else {
677 serializer.end_object()?;
678 continue;
679 };
680
681 stack.push(SerializeTask::Object {
682 entries,
683 first: false,
684 len,
685 });
686 stack.push(SerializeTask::EndField);
687 stack.push(SerializeTask::Value(value, Some(field)));
688 stack.push(SerializeTask::SerializeFieldName(field.name));
689 }
690 SerializeTask::Array { mut items, first } => {
691 if first {
692 serializer.start_array(Some(items.len()))?;
693 }
694
695 let Some(value) = items.next() else {
696 serializer.end_array()?;
697 continue;
698 };
699
700 stack.push(SerializeTask::Array {
701 items,
702 first: false,
703 });
704 stack.push(SerializeTask::Value(value, None));
705 }
706 SerializeTask::Set {
707 mut items,
708 first,
709 len,
710 } => {
711 if first {
712 serializer.start_array(Some(len))?;
713 }
714
715 let Some(value) = items.next() else {
716 serializer.end_array()?;
717 continue;
718 };
719
720 stack.push(SerializeTask::Set {
721 items,
722 first: false,
723 len,
724 });
725 stack.push(SerializeTask::Value(value, None));
726 }
727 SerializeTask::Map {
728 mut entries,
729 first,
730 len,
731 } => {
732 if first {
733 serializer.start_map(Some(len))?;
734 }
735
736 let Some((key, value)) = entries.next() else {
737 serializer.end_map()?;
738 continue;
739 };
740
741 stack.push(SerializeTask::Map {
742 entries,
743 first: false,
744 len,
745 });
746 stack.push(SerializeTask::SerializeMapValue(value));
747 stack.push(SerializeTask::SerializeMapKey(key));
748 }
749 SerializeTask::TupleStruct {
750 mut items,
751 first,
752 len,
753 } => {
754 if first {
755 serializer.start_array(Some(len))?;
756 }
757
758 let Some((field, value)) = items.next() else {
759 serializer.end_array()?;
760 continue;
761 };
762
763 stack.push(SerializeTask::TupleStruct {
764 items,
765 first: false,
766 len,
767 });
768 stack.push(SerializeTask::Value(value, Some(field)));
769 }
770 SerializeTask::Tuple { mut items, first } => {
771 if first {
772 serializer.start_array(Some(items.len()))?;
773 }
774
775 let Some((field, value)) = items.next() else {
776 serializer.end_array()?;
777 continue;
778 };
779
780 stack.push(SerializeTask::Tuple {
781 items,
782 first: false,
783 });
784 stack.push(SerializeTask::Value(value, Some(field)));
785 }
786
787 SerializeTask::SerializeFieldName(name) => {
789 serializer.serialize_field_name(name)?;
790 }
791 SerializeTask::SerializeMapKey(key_peek) => {
792 stack.push(SerializeTask::EndMapKey);
793 stack.push(SerializeTask::Value(key_peek, None));
794 serializer.begin_map_key()?;
795 }
796 SerializeTask::SerializeMapValue(value_peek) => {
797 stack.push(SerializeTask::EndMapValue);
798 stack.push(SerializeTask::Value(value_peek, None));
799 serializer.begin_map_value()?;
800 }
801
802 SerializeTask::EndObject => {
804 serializer.end_object()?;
805 }
806 SerializeTask::EndArray => {
807 serializer.end_array()?;
808 }
809 SerializeTask::EndMapKey => {
810 serializer.end_map_key()?;
811 }
812 SerializeTask::EndMapValue => {
813 serializer.end_map_value()?;
814 }
815 SerializeTask::EndField => {
816 serializer.end_field()?;
817 }
818 }
819 }
820
821 Ok(())
823}
824
825pub trait Serialize<'a>: Facet<'a> {
829 fn serialize<S: Serializer>(&'a self, serializer: &mut S) -> Result<(), S::Error>;
831}
832
833impl<'a, T> Serialize<'a> for T
834where
835 T: Facet<'a>,
836{
837 fn serialize<S: Serializer>(&'a self, serializer: &mut S) -> Result<(), S::Error> {
839 let peek = Peek::new(self);
840 serialize_iterative(peek, serializer)
841 }
842}
843
844#[cfg(test)]
845mod tests {
846 #[test]
847 fn it_works() {}
848}