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 match (cpeek.shape().def, cpeek.shape().ty) {
300 (Def::Scalar(sd), _) => {
301 let cpeek = cpeek.innermost_peek();
302
303 match cpeek.scalar_type() {
305 Some(ScalarType::Unit) => serializer.serialize_unit()?,
306 Some(ScalarType::Bool) => {
307 serializer.serialize_bool(*cpeek.get::<bool>().unwrap())?
308 }
309 Some(ScalarType::Char) => {
310 serializer.serialize_char(*cpeek.get::<char>().unwrap())?
311 }
312
313 Some(ScalarType::Str) => {
315 serializer.serialize_str(cpeek.get::<&str>().unwrap())?
316 }
317 Some(ScalarType::String) => {
318 serializer.serialize_str(cpeek.get::<String>().unwrap())?
319 }
320 Some(ScalarType::CowStr) => serializer.serialize_str(
321 cpeek.get::<alloc::borrow::Cow<'_, str>>().unwrap().as_ref(),
322 )?,
323
324 Some(ScalarType::F32) => {
326 serializer.serialize_f32(*cpeek.get::<f32>().unwrap())?
327 }
328 Some(ScalarType::F64) => {
329 serializer.serialize_f64(*cpeek.get::<f64>().unwrap())?
330 }
331
332 Some(ScalarType::U8) => {
334 serializer.serialize_u8(*cpeek.get::<u8>().unwrap())?
335 }
336 Some(ScalarType::U16) => {
337 serializer.serialize_u16(*cpeek.get::<u16>().unwrap())?
338 }
339 Some(ScalarType::U32) => {
340 serializer.serialize_u32(*cpeek.get::<u32>().unwrap())?
341 }
342 Some(ScalarType::U64) => {
343 serializer.serialize_u64(*cpeek.get::<u64>().unwrap())?
344 }
345 Some(ScalarType::U128) => {
346 serializer.serialize_u128(*cpeek.get::<u128>().unwrap())?
347 }
348 Some(ScalarType::USize) => {
349 serializer.serialize_usize(*cpeek.get::<usize>().unwrap())?
350 }
351 Some(ScalarType::I8) => {
352 serializer.serialize_i8(*cpeek.get::<i8>().unwrap())?
353 }
354 Some(ScalarType::I16) => {
355 serializer.serialize_i16(*cpeek.get::<i16>().unwrap())?
356 }
357 Some(ScalarType::I32) => {
358 serializer.serialize_i32(*cpeek.get::<i32>().unwrap())?
359 }
360 Some(ScalarType::I64) => {
361 serializer.serialize_i64(*cpeek.get::<i64>().unwrap())?
362 }
363 Some(ScalarType::I128) => {
364 serializer.serialize_i128(*cpeek.get::<i128>().unwrap())?
365 }
366 Some(ScalarType::ISize) => {
367 serializer.serialize_isize(*cpeek.get::<isize>().unwrap())?
368 }
369 Some(unsupported) => {
370 panic!("facet-serialize: unsupported scalar type: {unsupported:?}")
371 }
372 None => {
373 match sd.affinity {
374 ScalarAffinity::Time(_)
375 | ScalarAffinity::Path(_)
376 | ScalarAffinity::ULID(_)
377 | ScalarAffinity::UUID(_) => {
378 if let Some(_display) = (cpeek.shape().vtable.display)() {
379 serializer
381 .serialize_str(&alloc::format!("{}", cpeek))?
382 } else {
383 panic!(
384 "Unsupported shape (no display): {}",
385 cpeek.shape()
386 )
387 }
388 }
389 _ => {
390 panic!(
391 "Unsupported shape (unsupported affinity): {}",
392 cpeek.shape()
393 )
394 }
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> = peek
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::Option(_), _) => {
459 let opt = cpeek.into_option().unwrap();
460 if let Some(inner_peek) = opt.value() {
461 stack.push(SerializeTask::Value(inner_peek, None));
462 } else {
463 serializer.serialize_none()?;
464 }
465 }
466 (Def::SmartPointer(_), _) => {
467 let sp = cpeek.into_smart_pointer().unwrap();
471 if let Some(inner_peek) = sp.borrow_inner() {
472 stack.push(SerializeTask::Value(inner_peek, None));
474 } else {
475 todo!(
478 "Smart pointer without borrow support or with opaque pointee cannot be serialized"
479 );
480 }
481 }
482 (_, Type::User(UserType::Struct(sd))) => {
483 debug!("Serializing struct: shape={}", cpeek.shape(),);
484 debug!(
485 " Struct details: kind={:?}, field_count={}",
486 sd.kind,
487 sd.fields.len()
488 );
489
490 match sd.kind {
491 StructKind::Unit => {
492 debug!(" Handling unit struct (no fields)");
493 serializer.serialize_unit()?;
495 }
496 StructKind::Tuple => {
497 debug!(" Handling tuple with {} fields", sd.fields.len());
498 let peek_struct = cpeek.into_struct().unwrap();
499 let fields_iter = peek_struct.fields();
500 debug!(" Serializing {} fields as tuple", sd.fields.len());
501
502 stack.push(SerializeTask::Tuple {
503 items: fields_iter,
504 first: true,
505 });
506 trace!(
507 " Pushed TupleFields to stack for tuple, will handle {} fields",
508 sd.fields.len()
509 );
510 }
511 StructKind::TupleStruct => {
512 debug!(" Handling tuple struct");
513 let peek_struct = cpeek.into_struct().unwrap();
514 let fields = peek_struct.fields_for_serialize().count();
515 debug!(" Serializing {} fields as array", fields);
516
517 stack.push(SerializeTask::TupleStruct {
518 items: peek_struct.fields_for_serialize(),
519 first: true,
520 len: fields,
521 });
522 trace!(
523 " Pushed TupleStructFields to stack, will handle {} fields",
524 fields
525 );
526 }
527 StructKind::Struct => {
528 debug!(" Handling record struct");
529 let peek_struct = cpeek.into_struct().unwrap();
530 let fields = peek_struct.fields_for_serialize().count();
531 debug!(" Serializing {} fields as object", fields);
532
533 stack.push(SerializeTask::Object {
534 entries: peek_struct.fields_for_serialize(),
535 first: true,
536 len: fields,
537 });
538 trace!(
539 " Pushed ObjectFields to stack, will handle {} fields",
540 fields
541 );
542 }
543 _ => {
544 unreachable!()
545 }
546 }
547 }
548 (_, Type::User(UserType::Enum(_))) => {
549 let peek_enum = cpeek.into_enum().unwrap();
550 let variant = peek_enum
551 .active_variant()
552 .expect("Failed to get active variant");
553 let variant_index = peek_enum
554 .variant_index()
555 .expect("Failed to get variant index");
556 trace!(
557 "Active variant index is {}, variant is {:?}",
558 variant_index, variant
559 );
560 let discriminant = variant
561 .discriminant
562 .map(|d| d as u64)
563 .unwrap_or(variant_index as u64);
564 serializer.start_enum_variant(discriminant)?;
565 let flattened = maybe_field.map(|f| f.flattened).unwrap_or_default();
566
567 if variant.data.fields.is_empty() {
568 serializer.serialize_unit_variant(variant_index, variant.name)?;
570 } else {
571 if !flattened {
572 serializer.start_object(Some(1))?;
574 stack.push(SerializeTask::EndObject);
575
576 serializer.serialize_field_name(variant.name)?;
578 }
579
580 if variant_is_newtype_like(variant) {
581 let fields = peek_enum.fields_for_serialize().collect::<Vec<_>>();
583 let (field, field_peek) = fields[0];
584 stack.push(SerializeTask::Value(field_peek, Some(field)));
586 } else if variant.data.kind == StructKind::Tuple
587 || variant.data.kind == StructKind::TupleStruct
588 {
589 let fields = peek_enum.fields_for_serialize().count();
591 serializer.start_array(Some(fields))?;
592 stack.push(SerializeTask::EndArray);
593
594 let fields_for_serialize =
596 peek_enum.fields_for_serialize().collect::<Vec<_>>();
597 for (field, field_peek) in fields_for_serialize.into_iter().rev() {
598 stack.push(SerializeTask::Value(field_peek, Some(field)));
599 }
600 } else {
601 let fields = peek_enum.fields_for_serialize().count();
603 serializer.start_object(Some(fields))?;
604 stack.push(SerializeTask::EndObject);
605
606 let fields_for_serialize =
608 peek_enum.fields_for_serialize().collect::<Vec<_>>();
609 for (field, field_peek) in fields_for_serialize.into_iter().rev() {
610 stack.push(SerializeTask::EndField);
611 stack.push(SerializeTask::Value(field_peek, Some(field)));
612 stack.push(SerializeTask::SerializeFieldName(field.name));
613 }
614 }
615 }
616 }
617 (_, Type::Pointer(pointer_type)) => {
618 if let Some(str_value) = cpeek.as_str() {
620 serializer.serialize_str(str_value)?;
622 } else if let PointerType::Function(_) = pointer_type {
623 serializer.serialize_unit()?;
625 } else {
626 let innermost = cpeek.innermost_peek();
628 if innermost.shape() != cpeek.shape() {
629 stack.push(SerializeTask::Value(innermost, None));
631 } else {
632 serializer.serialize_unit()?;
634 }
635 }
636 }
637 _ => {
638 debug!(
640 "Unhandled type: {:?}, falling back to unit",
641 cpeek.shape().ty
642 );
643 serializer.serialize_unit()?;
644 }
645 }
646 }
647
648 SerializeTask::Object {
649 mut entries,
650 first,
651 len,
652 } => {
653 if first {
654 serializer.start_object(Some(len))?;
655 }
656
657 let Some((field, value)) = entries.next() else {
658 serializer.end_object()?;
659 continue;
660 };
661
662 stack.push(SerializeTask::Object {
663 entries,
664 first: false,
665 len,
666 });
667 stack.push(SerializeTask::EndField);
668 stack.push(SerializeTask::Value(value, Some(field)));
669 stack.push(SerializeTask::SerializeFieldName(field.name));
670 }
671 SerializeTask::Array { mut items, first } => {
672 if first {
673 serializer.start_array(Some(items.len()))?;
674 }
675
676 let Some(value) = items.next() else {
677 serializer.end_array()?;
678 continue;
679 };
680
681 stack.push(SerializeTask::Array {
682 items,
683 first: false,
684 });
685 stack.push(SerializeTask::Value(value, None));
686 }
687 SerializeTask::Map {
688 mut entries,
689 first,
690 len,
691 } => {
692 if first {
693 serializer.start_map(Some(len))?;
694 }
695
696 let Some((key, value)) = entries.next() else {
697 serializer.end_map()?;
698 continue;
699 };
700
701 stack.push(SerializeTask::Map {
702 entries,
703 first: false,
704 len,
705 });
706 stack.push(SerializeTask::SerializeMapValue(value));
707 stack.push(SerializeTask::SerializeMapKey(key));
708 }
709 SerializeTask::TupleStruct {
710 mut items,
711 first,
712 len,
713 } => {
714 if first {
715 serializer.start_array(Some(len))?;
716 }
717
718 let Some((field, value)) = items.next() else {
719 serializer.end_array()?;
720 continue;
721 };
722
723 stack.push(SerializeTask::TupleStruct {
724 items,
725 first: false,
726 len,
727 });
728 stack.push(SerializeTask::Value(value, Some(field)));
729 }
730 SerializeTask::Tuple { mut items, first } => {
731 if first {
732 serializer.start_array(Some(items.len()))?;
733 }
734
735 let Some((field, value)) = items.next() else {
736 serializer.end_array()?;
737 continue;
738 };
739
740 stack.push(SerializeTask::Tuple {
741 items,
742 first: false,
743 });
744 stack.push(SerializeTask::Value(value, Some(field)));
745 }
746
747 SerializeTask::SerializeFieldName(name) => {
749 serializer.serialize_field_name(name)?;
750 }
751 SerializeTask::SerializeMapKey(key_peek) => {
752 stack.push(SerializeTask::EndMapKey);
753 stack.push(SerializeTask::Value(key_peek, None));
754 serializer.begin_map_key()?;
755 }
756 SerializeTask::SerializeMapValue(value_peek) => {
757 stack.push(SerializeTask::EndMapValue);
758 stack.push(SerializeTask::Value(value_peek, None));
759 serializer.begin_map_value()?;
760 }
761
762 SerializeTask::EndObject => {
764 serializer.end_object()?;
765 }
766 SerializeTask::EndArray => {
767 serializer.end_array()?;
768 }
769 SerializeTask::EndMapKey => {
770 serializer.end_map_key()?;
771 }
772 SerializeTask::EndMapValue => {
773 serializer.end_map_value()?;
774 }
775 SerializeTask::EndField => {
776 serializer.end_field()?;
777 }
778 }
779 }
780
781 Ok(())
783}
784
785pub trait Serialize<'a>: Facet<'a> {
789 fn serialize<'shape, S: Serializer<'shape>>(
791 &'a self,
792 serializer: &mut S,
793 ) -> Result<(), S::Error>;
794}
795
796impl<'a, T> Serialize<'a> for T
797where
798 T: Facet<'a>,
799{
800 fn serialize<'shape, S: Serializer<'shape>>(
802 &'a self,
803 serializer: &mut S,
804 ) -> Result<(), S::Error> {
805 let peek = Peek::new(self);
806 serialize_iterative(peek, serializer)
807 }
808}