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