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