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 if cpeek
290 .shape()
291 .attributes
292 .contains(&ShapeAttribute::Transparent)
293 {
294 let old_shape = cpeek.shape();
295
296 let ps = cpeek.into_struct().unwrap();
298 cpeek = ps.field(0).unwrap();
299
300 let new_shape = cpeek.shape();
301 trace!(
302 "{old_shape} is transparent, let's serialize the inner {new_shape} instead"
303 );
304 }
305
306 trace!(
307 "Matching def={:?}, ty={:?} for shape={}",
308 cpeek.shape().def,
309 cpeek.shape().ty,
310 cpeek.shape()
311 );
312 match (cpeek.shape().def, cpeek.shape().ty) {
313 (Def::Scalar, _) => {
314 let cpeek = cpeek.innermost_peek();
315
316 match cpeek.scalar_type() {
318 Some(ScalarType::Unit) => serializer.serialize_unit()?,
319 Some(ScalarType::Bool) => {
320 serializer.serialize_bool(*cpeek.get::<bool>().unwrap())?
321 }
322 Some(ScalarType::Char) => {
323 serializer.serialize_char(*cpeek.get::<char>().unwrap())?
324 }
325
326 Some(ScalarType::Str) => {
328 serializer.serialize_str(cpeek.get::<str>().unwrap())?
329 }
330 Some(ScalarType::String) => {
331 serializer.serialize_str(cpeek.get::<String>().unwrap())?
332 }
333 Some(ScalarType::CowStr) => serializer.serialize_str(
334 cpeek.get::<alloc::borrow::Cow<'_, str>>().unwrap().as_ref(),
335 )?,
336
337 Some(ScalarType::F32) => {
339 serializer.serialize_f32(*cpeek.get::<f32>().unwrap())?
340 }
341 Some(ScalarType::F64) => {
342 serializer.serialize_f64(*cpeek.get::<f64>().unwrap())?
343 }
344
345 Some(ScalarType::U8) => {
347 serializer.serialize_u8(*cpeek.get::<u8>().unwrap())?
348 }
349 Some(ScalarType::U16) => {
350 serializer.serialize_u16(*cpeek.get::<u16>().unwrap())?
351 }
352 Some(ScalarType::U32) => {
353 serializer.serialize_u32(*cpeek.get::<u32>().unwrap())?
354 }
355 Some(ScalarType::U64) => {
356 serializer.serialize_u64(*cpeek.get::<u64>().unwrap())?
357 }
358 Some(ScalarType::U128) => {
359 serializer.serialize_u128(*cpeek.get::<u128>().unwrap())?
360 }
361 Some(ScalarType::USize) => {
362 serializer.serialize_usize(*cpeek.get::<usize>().unwrap())?
363 }
364 Some(ScalarType::I8) => {
365 serializer.serialize_i8(*cpeek.get::<i8>().unwrap())?
366 }
367 Some(ScalarType::I16) => {
368 serializer.serialize_i16(*cpeek.get::<i16>().unwrap())?
369 }
370 Some(ScalarType::I32) => {
371 serializer.serialize_i32(*cpeek.get::<i32>().unwrap())?
372 }
373 Some(ScalarType::I64) => {
374 serializer.serialize_i64(*cpeek.get::<i64>().unwrap())?
375 }
376 Some(ScalarType::I128) => {
377 serializer.serialize_i128(*cpeek.get::<i128>().unwrap())?
378 }
379 Some(ScalarType::ISize) => {
380 serializer.serialize_isize(*cpeek.get::<isize>().unwrap())?
381 }
382 Some(unsupported) => {
383 panic!("facet-serialize: unsupported scalar type: {unsupported:?}")
384 }
385 None => {
386 if let Some(_display) =
389 cpeek.shape().vtable.sized().and_then(|v| (v.display)())
390 {
391 serializer.serialize_str(&alloc::format!("{cpeek}"))?
393 } else {
394 panic!("Unsupported shape (no display): {}", cpeek.shape())
395 }
396 }
397 }
398 }
399 (Def::List(ld), _) => {
400 if ld.t().is_type::<u8>() {
401 if cpeek.shape().is_type::<Vec<u8>>() {
403 serializer.serialize_bytes(cpeek.get::<Vec<u8>>().unwrap())?
404 } else {
405 let peek_list = cpeek.into_list_like().unwrap();
408 stack.push(SerializeTask::Array {
409 items: peek_list.iter(),
410 first: true,
411 });
412 }
413 } else {
414 let peek_list = cpeek.into_list_like().unwrap();
415 stack.push(SerializeTask::Array {
416 items: peek_list.iter(),
417 first: true,
418 });
419 }
420 }
421 (Def::Array(ad), _) => {
422 if ad.t().is_type::<u8>() {
423 let bytes: Vec<u8> = cpeek
424 .into_list_like()
425 .unwrap()
426 .iter()
427 .map(|p| *p.get::<u8>().unwrap())
428 .collect();
429 serializer.serialize_bytes(&bytes)?;
430 } else {
431 let peek_list = cpeek.into_list_like().unwrap();
432 stack.push(SerializeTask::Array {
433 items: peek_list.iter(),
434 first: true,
435 });
436 }
437 }
438 (Def::Slice(sd), _) => {
439 if sd.t().is_type::<u8>() {
440 serializer.serialize_bytes(cpeek.get::<[u8]>().unwrap())?
441 } else {
442 let peek_list = cpeek.into_list_like().unwrap();
443 stack.push(SerializeTask::Array {
444 items: peek_list.iter(),
445 first: true,
446 });
447 }
448 }
449 (Def::Map(_), _) => {
450 let peek_map = cpeek.into_map().unwrap();
451 let len = peek_map.len();
452 stack.push(SerializeTask::Map {
453 entries: peek_map.iter(),
454 first: true,
455 len,
456 });
457 }
458 (Def::Set(_), _) => {
459 let peek_set = cpeek.into_set().unwrap();
460 stack.push(SerializeTask::Set {
461 items: peek_set.iter(),
462 first: true,
463 len: peek_set.len(),
464 });
465 }
466 (Def::Option(_), _) => {
467 let opt = cpeek.into_option().unwrap();
468 if let Some(inner_peek) = opt.value() {
469 serializer.start_some()?;
470 stack.push(SerializeTask::Value(inner_peek, None));
471 } else {
472 serializer.serialize_none()?;
473 }
474 }
475 (Def::Pointer(_), _) => {
476 let sp = cpeek.into_pointer().unwrap();
480 if let Some(inner_peek) = sp.borrow_inner() {
481 stack.push(SerializeTask::Value(inner_peek, None));
483 } else {
484 todo!(
487 "Smart pointer without borrow support or with opaque pointee cannot be serialized"
488 );
489 }
490 }
491 (_, Type::User(UserType::Struct(sd))) => {
492 trace!("Serializing struct: shape={}", cpeek.shape(),);
493 trace!(
494 " Struct details: kind={:?}, field_count={}",
495 sd.kind,
496 sd.fields.len()
497 );
498
499 match sd.kind {
500 StructKind::Unit => {
501 trace!(" Handling unit struct (no fields)");
502 serializer.serialize_unit()?;
504 }
505 StructKind::Tuple => {
506 trace!(" Handling tuple with {} fields", sd.fields.len());
507 let peek_struct = cpeek.into_struct().unwrap();
508 let fields_iter = peek_struct.fields();
509 trace!(" Serializing {} fields as tuple", sd.fields.len());
510
511 stack.push(SerializeTask::Tuple {
512 items: fields_iter,
513 first: true,
514 });
515 trace!(
516 " Pushed TupleFields to stack for tuple, will handle {} fields",
517 sd.fields.len()
518 );
519 }
520 StructKind::TupleStruct => {
521 trace!(" Handling tuple struct");
522 let peek_struct = cpeek.into_struct().unwrap();
523 let fields = peek_struct.fields_for_serialize().count();
524 trace!(" Serializing {fields} fields as array");
525
526 stack.push(SerializeTask::TupleStruct {
527 items: peek_struct.fields_for_serialize(),
528 first: true,
529 len: fields,
530 });
531 trace!(
532 " Pushed TupleStructFields to stack, will handle {fields} fields"
533 );
534 }
535 StructKind::Struct => {
536 trace!(" Handling record struct");
537 let peek_struct = cpeek.into_struct().unwrap();
538 let fields = peek_struct.fields_for_serialize().count();
539 trace!(" Serializing {fields} fields as object");
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} fields"
548 );
549 }
550 }
551 }
552 (_, Type::User(UserType::Enum(_))) => {
553 let peek_enum = cpeek.into_enum().unwrap();
554 let variant = peek_enum
555 .active_variant()
556 .expect("Failed to get active variant");
557 let variant_index = peek_enum
558 .variant_index()
559 .expect("Failed to get variant index");
560 trace!("Active variant index is {variant_index}, variant is {variant:?}");
561 let discriminant = variant
562 .discriminant
563 .map(|d| d as u64)
564 .unwrap_or(variant_index as u64);
565 serializer.start_enum_variant(discriminant)?;
566 let flattened = maybe_field.map(|f| f.flattened).unwrap_or_default();
567
568 if variant.data.fields.is_empty() {
569 serializer.serialize_unit_variant(variant_index, variant.name)?;
571 } else {
572 if !flattened {
573 serializer.start_object(Some(1))?;
575 stack.push(SerializeTask::EndObject);
576
577 serializer.serialize_field_name(variant.name)?;
579 }
580
581 if variant_is_newtype_like(variant) {
582 let fields = peek_enum.fields_for_serialize().collect::<Vec<_>>();
584 let (field, field_peek) = fields[0];
585 stack.push(SerializeTask::Value(field_peek, Some(field)));
587 } else if variant.data.kind == StructKind::Tuple
588 || variant.data.kind == StructKind::TupleStruct
589 {
590 let fields = peek_enum.fields_for_serialize().count();
592 serializer.start_array(Some(fields))?;
593 stack.push(SerializeTask::EndArray);
594
595 let fields_for_serialize =
597 peek_enum.fields_for_serialize().collect::<Vec<_>>();
598 for (field, field_peek) in fields_for_serialize.into_iter().rev() {
599 stack.push(SerializeTask::Value(field_peek, Some(field)));
600 }
601 } else {
602 let fields = peek_enum.fields_for_serialize().count();
604 serializer.start_object(Some(fields))?;
605 stack.push(SerializeTask::EndObject);
606
607 let fields_for_serialize =
609 peek_enum.fields_for_serialize().collect::<Vec<_>>();
610 for (field, field_peek) in fields_for_serialize.into_iter().rev() {
611 stack.push(SerializeTask::EndField);
612 stack.push(SerializeTask::Value(field_peek, Some(field)));
613 stack.push(SerializeTask::SerializeFieldName(field.name));
614 }
615 }
616 }
617 }
618 (_, Type::Pointer(pointer_type)) => {
619 if let Some(str_value) = cpeek.as_str() {
621 serializer.serialize_str(str_value)?;
623 } else if let Some(bytes) = cpeek.as_bytes() {
624 serializer.serialize_bytes(bytes)?;
626 } else if let PointerType::Function(_) = pointer_type {
627 serializer.serialize_unit()?;
629 } else {
630 let innermost = cpeek.innermost_peek();
632 if innermost.shape() != cpeek.shape() {
633 stack.push(SerializeTask::Value(innermost, None));
635 } else {
636 serializer.serialize_unit()?;
638 }
639 }
640 }
641 _ => {
642 trace!(
644 "Unhandled type: {:?}, falling back to unit",
645 cpeek.shape().ty
646 );
647 serializer.serialize_unit()?;
648 }
649 }
650 }
651
652 SerializeTask::Object {
653 mut entries,
654 first,
655 len,
656 } => {
657 if first {
658 serializer.start_object(Some(len))?;
659 }
660
661 let Some((field, value)) = entries.next() else {
662 serializer.end_object()?;
663 continue;
664 };
665
666 stack.push(SerializeTask::Object {
667 entries,
668 first: false,
669 len,
670 });
671 stack.push(SerializeTask::EndField);
672 stack.push(SerializeTask::Value(value, Some(field)));
673 stack.push(SerializeTask::SerializeFieldName(field.name));
674 }
675 SerializeTask::Array { mut items, first } => {
676 if first {
677 serializer.start_array(Some(items.len()))?;
678 }
679
680 let Some(value) = items.next() else {
681 serializer.end_array()?;
682 continue;
683 };
684
685 stack.push(SerializeTask::Array {
686 items,
687 first: false,
688 });
689 stack.push(SerializeTask::Value(value, None));
690 }
691 SerializeTask::Set {
692 mut items,
693 first,
694 len,
695 } => {
696 if first {
697 serializer.start_array(Some(len))?;
698 }
699
700 let Some(value) = items.next() else {
701 serializer.end_array()?;
702 continue;
703 };
704
705 stack.push(SerializeTask::Set {
706 items,
707 first: false,
708 len,
709 });
710 stack.push(SerializeTask::Value(value, None));
711 }
712 SerializeTask::Map {
713 mut entries,
714 first,
715 len,
716 } => {
717 if first {
718 serializer.start_map(Some(len))?;
719 }
720
721 let Some((key, value)) = entries.next() else {
722 serializer.end_map()?;
723 continue;
724 };
725
726 stack.push(SerializeTask::Map {
727 entries,
728 first: false,
729 len,
730 });
731 stack.push(SerializeTask::SerializeMapValue(value));
732 stack.push(SerializeTask::SerializeMapKey(key));
733 }
734 SerializeTask::TupleStruct {
735 mut items,
736 first,
737 len,
738 } => {
739 if first {
740 serializer.start_array(Some(len))?;
741 }
742
743 let Some((field, value)) = items.next() else {
744 serializer.end_array()?;
745 continue;
746 };
747
748 stack.push(SerializeTask::TupleStruct {
749 items,
750 first: false,
751 len,
752 });
753 stack.push(SerializeTask::Value(value, Some(field)));
754 }
755 SerializeTask::Tuple { mut items, first } => {
756 if first {
757 serializer.start_array(Some(items.len()))?;
758 }
759
760 let Some((field, value)) = items.next() else {
761 serializer.end_array()?;
762 continue;
763 };
764
765 stack.push(SerializeTask::Tuple {
766 items,
767 first: false,
768 });
769 stack.push(SerializeTask::Value(value, Some(field)));
770 }
771
772 SerializeTask::SerializeFieldName(name) => {
774 serializer.serialize_field_name(name)?;
775 }
776 SerializeTask::SerializeMapKey(key_peek) => {
777 stack.push(SerializeTask::EndMapKey);
778 stack.push(SerializeTask::Value(key_peek, None));
779 serializer.begin_map_key()?;
780 }
781 SerializeTask::SerializeMapValue(value_peek) => {
782 stack.push(SerializeTask::EndMapValue);
783 stack.push(SerializeTask::Value(value_peek, None));
784 serializer.begin_map_value()?;
785 }
786
787 SerializeTask::EndObject => {
789 serializer.end_object()?;
790 }
791 SerializeTask::EndArray => {
792 serializer.end_array()?;
793 }
794 SerializeTask::EndMapKey => {
795 serializer.end_map_key()?;
796 }
797 SerializeTask::EndMapValue => {
798 serializer.end_map_value()?;
799 }
800 SerializeTask::EndField => {
801 serializer.end_field()?;
802 }
803 }
804 }
805
806 Ok(())
808}
809
810pub trait Serialize<'a>: Facet<'a> {
814 fn serialize<S: Serializer>(&'a self, serializer: &mut S) -> Result<(), S::Error>;
816}
817
818impl<'a, T> Serialize<'a> for T
819where
820 T: Facet<'a>,
821{
822 fn serialize<S: Serializer>(&'a self, serializer: &mut S) -> Result<(), S::Error> {
824 let peek = Peek::new(self);
825 serialize_iterative(peek, serializer)
826 }
827}
828
829#[cfg(test)]
830mod tests {
831 #[test]
832 fn it_works() {}
833}