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