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) =
385 cpeek.shape().vtable.sized().and_then(|v| (v.display)())
386 {
387 serializer
389 .serialize_str(&alloc::format!("{}", cpeek))?
390 } else {
391 panic!(
392 "Unsupported shape (no display): {}",
393 cpeek.shape()
394 )
395 }
396 }
397 _ => {
398 panic!(
399 "Unsupported shape (unsupported affinity): {}",
400 cpeek.shape()
401 )
402 }
403 }
404 }
405 }
406 }
407 (Def::List(ld), _) => {
408 if ld.t().is_type::<u8>() {
409 if cpeek.shape().is_type::<Vec<u8>>() {
411 serializer.serialize_bytes(cpeek.get::<Vec<u8>>().unwrap())?
412 } else {
413 let peek_list = cpeek.into_list_like().unwrap();
416 stack.push(SerializeTask::Array {
417 items: peek_list.iter(),
418 first: true,
419 });
420 }
421 } else {
422 let peek_list = cpeek.into_list_like().unwrap();
423 stack.push(SerializeTask::Array {
424 items: peek_list.iter(),
425 first: true,
426 });
427 }
428 }
429 (Def::Array(ad), _) => {
430 if ad.t().is_type::<u8>() {
431 let bytes: Vec<u8> = cpeek
432 .into_list_like()
433 .unwrap()
434 .iter()
435 .map(|p| *p.get::<u8>().unwrap())
436 .collect();
437 serializer.serialize_bytes(&bytes)?;
438 } else {
439 let peek_list = cpeek.into_list_like().unwrap();
440 stack.push(SerializeTask::Array {
441 items: peek_list.iter(),
442 first: true,
443 });
444 }
445 }
446 (Def::Slice(sd), _) => {
447 if sd.t().is_type::<u8>() {
448 serializer.serialize_bytes(cpeek.get::<&[u8]>().unwrap())?
449 } else {
450 let peek_list = cpeek.into_list_like().unwrap();
451 stack.push(SerializeTask::Array {
452 items: peek_list.iter(),
453 first: true,
454 });
455 }
456 }
457 (Def::Map(_), _) => {
458 let peek_map = cpeek.into_map().unwrap();
459 let len = peek_map.len();
460 stack.push(SerializeTask::Map {
461 entries: peek_map.iter(),
462 first: true,
463 len,
464 });
465 }
466 (Def::Option(_), _) => {
467 let opt = cpeek.into_option().unwrap();
468 if let Some(inner_peek) = opt.value() {
469 stack.push(SerializeTask::Value(inner_peek, None));
470 } else {
471 serializer.serialize_none()?;
472 }
473 }
474 (Def::SmartPointer(_), _) => {
475 let sp = cpeek.into_smart_pointer().unwrap();
479 if let Some(inner_peek) = sp.borrow_inner() {
480 stack.push(SerializeTask::Value(inner_peek, None));
482 } else {
483 todo!(
486 "Smart pointer without borrow support or with opaque pointee cannot be serialized"
487 );
488 }
489 }
490 (_, Type::User(UserType::Struct(sd))) => {
491 debug!("Serializing struct: shape={}", cpeek.shape(),);
492 debug!(
493 " Struct details: kind={:?}, field_count={}",
494 sd.kind,
495 sd.fields.len()
496 );
497
498 match sd.kind {
499 StructKind::Unit => {
500 debug!(" Handling unit struct (no fields)");
501 serializer.serialize_unit()?;
503 }
504 StructKind::Tuple => {
505 debug!(" Handling tuple with {} fields", sd.fields.len());
506 let peek_struct = cpeek.into_struct().unwrap();
507 let fields_iter = peek_struct.fields();
508 debug!(" Serializing {} fields as tuple", sd.fields.len());
509
510 stack.push(SerializeTask::Tuple {
511 items: fields_iter,
512 first: true,
513 });
514 trace!(
515 " Pushed TupleFields to stack for tuple, will handle {} fields",
516 sd.fields.len()
517 );
518 }
519 StructKind::TupleStruct => {
520 debug!(" Handling tuple struct");
521 let peek_struct = cpeek.into_struct().unwrap();
522 let fields = peek_struct.fields_for_serialize().count();
523 debug!(" Serializing {} fields as array", fields);
524
525 stack.push(SerializeTask::TupleStruct {
526 items: peek_struct.fields_for_serialize(),
527 first: true,
528 len: fields,
529 });
530 trace!(
531 " Pushed TupleStructFields to stack, will handle {} fields",
532 fields
533 );
534 }
535 StructKind::Struct => {
536 debug!(" Handling record struct");
537 let peek_struct = cpeek.into_struct().unwrap();
538 let fields = peek_struct.fields_for_serialize().count();
539 debug!(" Serializing {} fields as object", fields);
540
541 stack.push(SerializeTask::Object {
542 entries: peek_struct.fields_for_serialize(),
543 first: true,
544 len: fields,
545 });
546 trace!(
547 " Pushed ObjectFields to stack, will handle {} fields",
548 fields
549 );
550 }
551 _ => {
552 unreachable!()
553 }
554 }
555 }
556 (_, Type::User(UserType::Enum(_))) => {
557 let peek_enum = cpeek.into_enum().unwrap();
558 let variant = peek_enum
559 .active_variant()
560 .expect("Failed to get active variant");
561 let variant_index = peek_enum
562 .variant_index()
563 .expect("Failed to get variant index");
564 trace!(
565 "Active variant index is {}, variant is {:?}",
566 variant_index, variant
567 );
568 let discriminant = variant
569 .discriminant
570 .map(|d| d as u64)
571 .unwrap_or(variant_index as u64);
572 serializer.start_enum_variant(discriminant)?;
573 let flattened = maybe_field.map(|f| f.flattened).unwrap_or_default();
574
575 if variant.data.fields.is_empty() {
576 serializer.serialize_unit_variant(variant_index, variant.name)?;
578 } else {
579 if !flattened {
580 serializer.start_object(Some(1))?;
582 stack.push(SerializeTask::EndObject);
583
584 serializer.serialize_field_name(variant.name)?;
586 }
587
588 if variant_is_newtype_like(variant) {
589 let fields = peek_enum.fields_for_serialize().collect::<Vec<_>>();
591 let (field, field_peek) = fields[0];
592 stack.push(SerializeTask::Value(field_peek, Some(field)));
594 } else if variant.data.kind == StructKind::Tuple
595 || variant.data.kind == StructKind::TupleStruct
596 {
597 let fields = peek_enum.fields_for_serialize().count();
599 serializer.start_array(Some(fields))?;
600 stack.push(SerializeTask::EndArray);
601
602 let fields_for_serialize =
604 peek_enum.fields_for_serialize().collect::<Vec<_>>();
605 for (field, field_peek) in fields_for_serialize.into_iter().rev() {
606 stack.push(SerializeTask::Value(field_peek, Some(field)));
607 }
608 } else {
609 let fields = peek_enum.fields_for_serialize().count();
611 serializer.start_object(Some(fields))?;
612 stack.push(SerializeTask::EndObject);
613
614 let fields_for_serialize =
616 peek_enum.fields_for_serialize().collect::<Vec<_>>();
617 for (field, field_peek) in fields_for_serialize.into_iter().rev() {
618 stack.push(SerializeTask::EndField);
619 stack.push(SerializeTask::Value(field_peek, Some(field)));
620 stack.push(SerializeTask::SerializeFieldName(field.name));
621 }
622 }
623 }
624 }
625 (_, Type::Pointer(pointer_type)) => {
626 if let Some(str_value) = cpeek.as_str() {
628 serializer.serialize_str(str_value)?;
630 } else if let Some(bytes) = cpeek.as_bytes() {
631 serializer.serialize_bytes(bytes)?;
633 } else if let PointerType::Function(_) = pointer_type {
634 serializer.serialize_unit()?;
636 } else {
637 let innermost = cpeek.innermost_peek();
639 if innermost.shape() != cpeek.shape() {
640 stack.push(SerializeTask::Value(innermost, None));
642 } else {
643 serializer.serialize_unit()?;
645 }
646 }
647 }
648 _ => {
649 debug!(
651 "Unhandled type: {:?}, falling back to unit",
652 cpeek.shape().ty
653 );
654 serializer.serialize_unit()?;
655 }
656 }
657 }
658
659 SerializeTask::Object {
660 mut entries,
661 first,
662 len,
663 } => {
664 if first {
665 serializer.start_object(Some(len))?;
666 }
667
668 let Some((field, value)) = entries.next() else {
669 serializer.end_object()?;
670 continue;
671 };
672
673 stack.push(SerializeTask::Object {
674 entries,
675 first: false,
676 len,
677 });
678 stack.push(SerializeTask::EndField);
679 stack.push(SerializeTask::Value(value, Some(field)));
680 stack.push(SerializeTask::SerializeFieldName(field.name));
681 }
682 SerializeTask::Array { mut items, first } => {
683 if first {
684 serializer.start_array(Some(items.len()))?;
685 }
686
687 let Some(value) = items.next() else {
688 serializer.end_array()?;
689 continue;
690 };
691
692 stack.push(SerializeTask::Array {
693 items,
694 first: false,
695 });
696 stack.push(SerializeTask::Value(value, None));
697 }
698 SerializeTask::Map {
699 mut entries,
700 first,
701 len,
702 } => {
703 if first {
704 serializer.start_map(Some(len))?;
705 }
706
707 let Some((key, value)) = entries.next() else {
708 serializer.end_map()?;
709 continue;
710 };
711
712 stack.push(SerializeTask::Map {
713 entries,
714 first: false,
715 len,
716 });
717 stack.push(SerializeTask::SerializeMapValue(value));
718 stack.push(SerializeTask::SerializeMapKey(key));
719 }
720 SerializeTask::TupleStruct {
721 mut items,
722 first,
723 len,
724 } => {
725 if first {
726 serializer.start_array(Some(len))?;
727 }
728
729 let Some((field, value)) = items.next() else {
730 serializer.end_array()?;
731 continue;
732 };
733
734 stack.push(SerializeTask::TupleStruct {
735 items,
736 first: false,
737 len,
738 });
739 stack.push(SerializeTask::Value(value, Some(field)));
740 }
741 SerializeTask::Tuple { mut items, first } => {
742 if first {
743 serializer.start_array(Some(items.len()))?;
744 }
745
746 let Some((field, value)) = items.next() else {
747 serializer.end_array()?;
748 continue;
749 };
750
751 stack.push(SerializeTask::Tuple {
752 items,
753 first: false,
754 });
755 stack.push(SerializeTask::Value(value, Some(field)));
756 }
757
758 SerializeTask::SerializeFieldName(name) => {
760 serializer.serialize_field_name(name)?;
761 }
762 SerializeTask::SerializeMapKey(key_peek) => {
763 stack.push(SerializeTask::EndMapKey);
764 stack.push(SerializeTask::Value(key_peek, None));
765 serializer.begin_map_key()?;
766 }
767 SerializeTask::SerializeMapValue(value_peek) => {
768 stack.push(SerializeTask::EndMapValue);
769 stack.push(SerializeTask::Value(value_peek, None));
770 serializer.begin_map_value()?;
771 }
772
773 SerializeTask::EndObject => {
775 serializer.end_object()?;
776 }
777 SerializeTask::EndArray => {
778 serializer.end_array()?;
779 }
780 SerializeTask::EndMapKey => {
781 serializer.end_map_key()?;
782 }
783 SerializeTask::EndMapValue => {
784 serializer.end_map_value()?;
785 }
786 SerializeTask::EndField => {
787 serializer.end_field()?;
788 }
789 }
790 }
791
792 Ok(())
794}
795
796pub trait Serialize<'a>: Facet<'a> {
800 fn serialize<'shape, S: Serializer<'shape>>(
802 &'a self,
803 serializer: &mut S,
804 ) -> Result<(), S::Error>;
805}
806
807impl<'a, T> Serialize<'a> for T
808where
809 T: Facet<'a>,
810{
811 fn serialize<'shape, S: Serializer<'shape>>(
813 &'a self,
814 serializer: &mut S,
815 ) -> Result<(), S::Error> {
816 let peek = Peek::new(self);
817 serialize_iterative(peek, serializer)
818 }
819}