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::{HasFields, Peek, PeekListLike, PeekMap, PeekStruct, PeekTuple, ScalarType};
18use log::{debug, trace};
19
20mod debug_serializer;
21
22fn variant_is_newtype_like(variant: &facet_core::Variant) -> bool {
23 variant.data.kind == facet_core::StructKind::Tuple && variant.data.fields.len() == 1
24}
25
26pub trait Serializer<'shape> {
31 type Error;
33
34 fn serialize_u64(&mut self, value: u64) -> Result<(), Self::Error>;
36
37 fn serialize_u128(&mut self, value: u128) -> Result<(), Self::Error>;
39
40 fn serialize_i64(&mut self, value: i64) -> Result<(), Self::Error>;
42
43 fn serialize_i128(&mut self, value: i128) -> Result<(), Self::Error>;
45
46 fn serialize_f64(&mut self, value: f64) -> Result<(), Self::Error>;
48
49 fn serialize_bool(&mut self, value: bool) -> Result<(), Self::Error>;
51
52 fn serialize_char(&mut self, value: char) -> Result<(), Self::Error>;
54
55 fn serialize_str(&mut self, value: &str) -> Result<(), Self::Error>;
57
58 fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error>;
60
61 fn serialize_none(&mut self) -> Result<(), Self::Error>;
65
66 fn serialize_unit(&mut self) -> Result<(), Self::Error>;
68
69 fn serialize_unit_variant(
78 &mut self,
79 variant_index: usize,
80 variant_name: &'shape str,
81 ) -> Result<(), Self::Error>;
82
83 fn start_object(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
89
90 fn serialize_field_name(&mut self, name: &'shape str) -> Result<(), Self::Error>;
96
97 fn start_array(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
103
104 fn start_map(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
110
111 #[inline(always)]
113 fn serialize_u8(&mut self, value: u8) -> Result<(), Self::Error> {
114 self.serialize_u64(value as u64)
115 }
116
117 #[inline(always)]
119 fn serialize_u16(&mut self, value: u16) -> Result<(), Self::Error> {
120 self.serialize_u64(value as u64)
121 }
122
123 #[inline(always)]
125 fn serialize_u32(&mut self, value: u32) -> Result<(), Self::Error> {
126 self.serialize_u64(value as u64)
127 }
128
129 #[inline(always)]
131 fn serialize_usize(&mut self, value: usize) -> Result<(), Self::Error> {
132 self.serialize_u64(value as u64)
134 }
135
136 #[inline(always)]
138 fn serialize_i8(&mut self, value: i8) -> Result<(), Self::Error> {
139 self.serialize_i64(value as i64)
140 }
141
142 #[inline(always)]
144 fn serialize_i16(&mut self, value: i16) -> Result<(), Self::Error> {
145 self.serialize_i64(value as i64)
146 }
147
148 #[inline(always)]
150 fn serialize_i32(&mut self, value: i32) -> Result<(), Self::Error> {
151 self.serialize_i64(value as i64)
152 }
153
154 #[inline(always)]
156 fn serialize_isize(&mut self, value: isize) -> Result<(), Self::Error> {
157 self.serialize_i64(value as i64)
159 }
160
161 #[inline(always)]
163 fn serialize_f32(&mut self, value: f32) -> Result<(), Self::Error> {
164 self.serialize_f64(value as f64)
165 }
166
167 #[inline(always)]
169 fn begin_map_key(&mut self) -> Result<(), Self::Error> {
170 Ok(())
171 }
172
173 #[inline(always)]
175 fn end_map_key(&mut self) -> Result<(), Self::Error> {
176 Ok(())
177 }
178
179 #[inline(always)]
181 fn begin_map_value(&mut self) -> Result<(), Self::Error> {
182 Ok(())
183 }
184
185 #[inline(always)]
187 fn end_map_value(&mut self) -> Result<(), Self::Error> {
188 Ok(())
189 }
190
191 #[inline(always)]
193 fn end_object(&mut self) -> Result<(), Self::Error> {
194 Ok(())
195 }
196
197 #[inline(always)]
199 fn end_array(&mut self) -> Result<(), Self::Error> {
200 Ok(())
201 }
202
203 #[inline(always)]
205 fn end_map(&mut self) -> Result<(), Self::Error> {
206 Ok(())
207 }
208
209 #[inline(always)]
211 fn end_field(&mut self) -> Result<(), Self::Error> {
212 Ok(())
213 }
214
215 #[inline(always)]
217 fn start_enum_variant(&mut self, discriminant: u64) -> Result<(), Self::Error> {
218 let _ = discriminant;
219 Ok(())
220 }
221}
222
223#[derive(Debug)]
227enum SerializeTask<'mem, 'facet, 'shape> {
228 Value(Peek<'mem, 'facet, 'shape>, Option<Field<'shape>>),
229 EndObject,
231 EndArray,
232 EndMap,
233 EndMapKey,
234 EndMapValue,
235 EndField,
236 ObjectFields(PeekStruct<'mem, 'facet, 'shape>),
238 ArrayItems(PeekListLike<'mem, 'facet, 'shape>),
239 TupleStructFields(PeekStruct<'mem, 'facet, 'shape>),
240 TupleFields(PeekTuple<'mem, 'facet, 'shape>),
241 MapEntries(PeekMap<'mem, 'facet, 'shape>),
242 SerializeFieldName(&'shape str),
244 SerializeMapKey(Peek<'mem, 'facet, 'shape>),
245 SerializeMapValue(Peek<'mem, 'facet, 'shape>),
246}
247
248pub fn serialize_iterative<'mem, 'facet, 'shape, S>(
252 peek: Peek<'mem, 'facet, 'shape>,
253 serializer: &mut S,
254) -> Result<(), S::Error>
255where
256 S: Serializer<'shape>,
257{
258 let mut stack = Vec::new();
259 stack.push(SerializeTask::Value(peek, None));
260
261 while let Some(task) = stack.pop() {
262 match task {
263 SerializeTask::Value(mut cpeek, maybe_field) => {
264 debug!("Serializing a value, shape is {}", cpeek.shape());
265
266 if cpeek
267 .shape()
268 .attributes
269 .contains(&ShapeAttribute::Transparent)
270 {
271 let old_shape = cpeek.shape();
272
273 let ps = cpeek.into_struct().unwrap();
275 cpeek = ps.field(0).unwrap();
276
277 let new_shape = cpeek.shape();
278 debug!(
279 "{old_shape} is transparent, let's serialize the inner {new_shape} instead"
280 );
281 }
282
283 match (cpeek.shape().def, cpeek.shape().ty) {
284 (Def::Scalar(sd), _) => {
285 let cpeek = cpeek.innermost_peek();
286
287 match cpeek.scalar_type() {
289 Some(ScalarType::Unit) => serializer.serialize_unit()?,
290 Some(ScalarType::Bool) => {
291 serializer.serialize_bool(*cpeek.get::<bool>().unwrap())?
292 }
293 Some(ScalarType::Char) => {
294 serializer.serialize_char(*cpeek.get::<char>().unwrap())?
295 }
296
297 Some(ScalarType::Str) => {
299 serializer.serialize_str(cpeek.get::<&str>().unwrap())?
300 }
301 Some(ScalarType::String) => {
302 serializer.serialize_str(cpeek.get::<String>().unwrap())?
303 }
304 Some(ScalarType::CowStr) => serializer.serialize_str(
305 cpeek.get::<alloc::borrow::Cow<'_, str>>().unwrap().as_ref(),
306 )?,
307
308 Some(ScalarType::F32) => {
310 serializer.serialize_f32(*cpeek.get::<f32>().unwrap())?
311 }
312 Some(ScalarType::F64) => {
313 serializer.serialize_f64(*cpeek.get::<f64>().unwrap())?
314 }
315
316 Some(ScalarType::U8) => {
318 serializer.serialize_u8(*cpeek.get::<u8>().unwrap())?
319 }
320 Some(ScalarType::U16) => {
321 serializer.serialize_u16(*cpeek.get::<u16>().unwrap())?
322 }
323 Some(ScalarType::U32) => {
324 serializer.serialize_u32(*cpeek.get::<u32>().unwrap())?
325 }
326 Some(ScalarType::U64) => {
327 serializer.serialize_u64(*cpeek.get::<u64>().unwrap())?
328 }
329 Some(ScalarType::U128) => {
330 serializer.serialize_u128(*cpeek.get::<u128>().unwrap())?
331 }
332 Some(ScalarType::USize) => {
333 serializer.serialize_usize(*cpeek.get::<usize>().unwrap())?
334 }
335 Some(ScalarType::I8) => {
336 serializer.serialize_i8(*cpeek.get::<i8>().unwrap())?
337 }
338 Some(ScalarType::I16) => {
339 serializer.serialize_i16(*cpeek.get::<i16>().unwrap())?
340 }
341 Some(ScalarType::I32) => {
342 serializer.serialize_i32(*cpeek.get::<i32>().unwrap())?
343 }
344 Some(ScalarType::I64) => {
345 serializer.serialize_i64(*cpeek.get::<i64>().unwrap())?
346 }
347 Some(ScalarType::I128) => {
348 serializer.serialize_i128(*cpeek.get::<i128>().unwrap())?
349 }
350 Some(ScalarType::ISize) => {
351 serializer.serialize_isize(*cpeek.get::<isize>().unwrap())?
352 }
353 Some(unsupported) => {
354 panic!("facet-serialize: unsupported scalar type: {unsupported:?}")
355 }
356 None => {
357 match sd.affinity {
358 ScalarAffinity::Time(_)
359 | ScalarAffinity::Path(_)
360 | ScalarAffinity::ULID(_)
361 | ScalarAffinity::UUID(_) => {
362 if let Some(_display) = cpeek.shape().vtable.display {
363 serializer
365 .serialize_str(&alloc::format!("{}", cpeek))?
366 } else {
367 panic!(
368 "Unsupported shape (no display): {}",
369 cpeek.shape()
370 )
371 }
372 }
373 _ => {
374 panic!(
375 "Unsupported shape (unsupported affinity): {}",
376 cpeek.shape()
377 )
378 }
379 }
380 }
381 }
382 }
383 (Def::List(ld), _) => {
384 if ld.t().is_type::<u8>() {
385 serializer.serialize_bytes(cpeek.get::<Vec<u8>>().unwrap())?
386 } else {
387 let peek_list = cpeek.into_list_like().unwrap();
388 let len = peek_list.len();
389 serializer.start_array(Some(len))?;
390 stack.push(SerializeTask::EndArray);
391 stack.push(SerializeTask::ArrayItems(peek_list));
392 }
393 }
394 (Def::Array(ad), _) => {
395 if ad.t().is_type::<u8>() {
396 let bytes: Vec<u8> = peek
397 .into_list_like()
398 .unwrap()
399 .iter()
400 .map(|p| *p.get::<u8>().unwrap())
401 .collect();
402 serializer.serialize_bytes(&bytes)?;
403 } else {
404 let peek_list = cpeek.into_list_like().unwrap();
405 let len = peek_list.len();
406 serializer.start_array(Some(len))?;
407 stack.push(SerializeTask::EndArray);
408 stack.push(SerializeTask::ArrayItems(peek_list));
409 }
410 }
411 (Def::Slice(sd), _) => {
412 if sd.t().is_type::<u8>() {
413 serializer.serialize_bytes(cpeek.get::<&[u8]>().unwrap())?
414 } else {
415 let peek_list = cpeek.into_list_like().unwrap();
416 let len = peek_list.len();
417 serializer.start_array(Some(len))?;
418 stack.push(SerializeTask::EndArray);
419 stack.push(SerializeTask::ArrayItems(peek_list));
420 }
421 }
422 (Def::Map(_), _) => {
423 let peek_map = cpeek.into_map().unwrap();
424 let len = peek_map.len();
425 serializer.start_map(Some(len))?;
426 stack.push(SerializeTask::EndMap);
427 stack.push(SerializeTask::MapEntries(peek_map));
428 }
429 (Def::Option(_), _) => {
430 let opt = cpeek.into_option().unwrap();
431 if let Some(inner_peek) = opt.value() {
432 stack.push(SerializeTask::Value(inner_peek, None));
433 } else {
434 serializer.serialize_none()?;
435 }
436 }
437 (Def::SmartPointer(_), _) => {
438 let _sp = cpeek.into_smart_pointer().unwrap();
439 panic!("TODO: Implement serialization for smart pointers");
440 }
441 (_, Type::User(UserType::Struct(sd))) => {
442 debug!("Serializing struct: shape={}", cpeek.shape(),);
443 debug!(
444 " Struct details: kind={:?}, field_count={}",
445 sd.kind,
446 sd.fields.len()
447 );
448
449 match sd.kind {
450 StructKind::Unit => {
451 debug!(" Handling unit struct (no fields)");
452 serializer.serialize_unit()?;
454 }
455 StructKind::Tuple | StructKind::TupleStruct => {
456 debug!(" Handling tuple struct with {:?} kind", sd.kind);
457 let peek_struct = cpeek.into_struct().unwrap();
458 let fields = peek_struct.fields_for_serialize().count();
459 debug!(" Serializing {} fields as array", fields);
460
461 serializer.start_array(Some(fields))?;
462 stack.push(SerializeTask::EndArray);
463 stack.push(SerializeTask::TupleStructFields(peek_struct));
464 trace!(
465 " Pushed TupleStructFields to stack, will handle {} fields",
466 fields
467 );
468 }
469 StructKind::Struct => {
470 debug!(" Handling record struct");
471 let peek_struct = cpeek.into_struct().unwrap();
472 let fields = peek_struct.fields_for_serialize().count();
473 debug!(" Serializing {} fields as object", fields);
474
475 serializer.start_object(Some(fields))?;
476 stack.push(SerializeTask::EndObject);
477 stack.push(SerializeTask::ObjectFields(peek_struct));
478 trace!(
479 " Pushed ObjectFields to stack, will handle {} fields",
480 fields
481 );
482 }
483 _ => {
484 unreachable!()
485 }
486 }
487 }
488 (_, Type::Sequence(SequenceType::Tuple(_))) => {
489 debug!("Serializing tuple: shape={}", cpeek.shape(),);
490
491 if let Ok(peek_tuple) = cpeek.into_tuple() {
493 let count = peek_tuple.len();
494 debug!(" Tuple fields count: {}", count);
495
496 serializer.start_array(Some(count))?;
497 stack.push(SerializeTask::EndArray);
498 stack.push(SerializeTask::TupleFields(peek_tuple));
499 trace!(
500 " Pushed TupleFields to stack for tuple, will handle {} fields",
501 count
502 );
503 } else {
504 debug!(
507 " Could not convert to PeekTuple, falling back to list_like approach"
508 );
509
510 if let Ok(peek_list_like) = cpeek.into_list_like() {
511 let count = peek_list_like.len();
512 serializer.start_array(Some(count))?;
513 stack.push(SerializeTask::EndArray);
514 stack.push(SerializeTask::ArrayItems(peek_list_like));
515 trace!(" Pushed ArrayItems to stack for tuple serialization",);
516 } else {
517 debug!(
519 " Could not convert tuple to list-like either, using empty array"
520 );
521 serializer.start_array(Some(0))?;
522 stack.push(SerializeTask::EndArray);
523 trace!(" Warning: Tuple serialization fallback to empty array");
524 }
525 }
526 }
527 (_, Type::User(UserType::Enum(_))) => {
528 let peek_enum = cpeek.into_enum().unwrap();
529 let variant = peek_enum
530 .active_variant()
531 .expect("Failed to get active variant");
532 let variant_index = peek_enum
533 .variant_index()
534 .expect("Failed to get variant index");
535 trace!(
536 "Active variant index is {}, variant is {:?}",
537 variant_index, variant
538 );
539 let discriminant = variant
540 .discriminant
541 .map(|d| d as u64)
542 .unwrap_or(variant_index as u64);
543 serializer.start_enum_variant(discriminant)?;
544 let flattened = maybe_field.map(|f| f.flattened).unwrap_or_default();
545
546 if variant.data.fields.is_empty() {
547 serializer.serialize_unit_variant(variant_index, variant.name)?;
549 } else {
550 if !flattened {
551 serializer.start_object(Some(1))?;
553 stack.push(SerializeTask::EndObject);
554
555 serializer.serialize_field_name(variant.name)?;
557 }
558
559 if variant_is_newtype_like(variant) {
560 let fields = peek_enum.fields_for_serialize().collect::<Vec<_>>();
562 let (field, field_peek) = fields[0];
563 stack.push(SerializeTask::Value(field_peek, Some(field)));
565 } else if variant.data.kind == StructKind::Tuple
566 || variant.data.kind == StructKind::TupleStruct
567 {
568 let fields = peek_enum.fields_for_serialize().count();
570 serializer.start_array(Some(fields))?;
571 stack.push(SerializeTask::EndArray);
572
573 for (field, field_peek) in peek_enum.fields_for_serialize().rev() {
575 stack.push(SerializeTask::Value(field_peek, Some(field)));
576 }
577 } else {
578 let fields = peek_enum.fields_for_serialize().count();
580 serializer.start_object(Some(fields))?;
581 stack.push(SerializeTask::EndObject);
582
583 for (field, field_peek) in peek_enum.fields_for_serialize().rev() {
585 stack.push(SerializeTask::EndField);
586 stack.push(SerializeTask::Value(field_peek, Some(field)));
587 stack.push(SerializeTask::SerializeFieldName(field.name));
588 }
589 }
590 }
591 }
592 (_, Type::Pointer(pointer_type)) => {
593 if let Some(str_value) = cpeek.as_str() {
595 serializer.serialize_str(str_value)?;
597 } else if let PointerType::Function(_) = pointer_type {
598 serializer.serialize_unit()?;
600 } else {
601 let innermost = cpeek.innermost_peek();
603 if innermost.shape() != cpeek.shape() {
604 stack.push(SerializeTask::Value(innermost, None));
606 } else {
607 serializer.serialize_unit()?;
609 }
610 }
611 }
612 _ => {
613 debug!(
615 "Unhandled type: {:?}, falling back to unit",
616 cpeek.shape().ty
617 );
618 serializer.serialize_unit()?;
619 }
620 }
621 }
622
623 SerializeTask::ObjectFields(peek_struct) => {
625 for (field, field_peek) in peek_struct.fields_for_serialize().rev() {
627 stack.push(SerializeTask::EndField);
628 stack.push(SerializeTask::Value(field_peek, Some(field)));
629 stack.push(SerializeTask::SerializeFieldName(field.name));
630 }
631 }
632 SerializeTask::TupleStructFields(peek_struct) => {
633 for (field, field_peek) in peek_struct.fields_for_serialize().rev() {
635 stack.push(SerializeTask::Value(field_peek, Some(field)));
636 }
637 }
638 SerializeTask::TupleFields(peek_tuple) => {
639 for (_, field_peek) in peek_tuple.fields().rev() {
641 let innermost_peek = field_peek.innermost_peek();
644
645 stack.push(SerializeTask::Value(innermost_peek, None));
647 }
648 trace!(" Pushed {} tuple fields to stack", peek_tuple.len());
649 }
650 SerializeTask::ArrayItems(peek_list) => {
651 let items: Vec<_> = peek_list.iter().collect();
653 for item_peek in items.into_iter().rev() {
654 stack.push(SerializeTask::Value(item_peek, None));
655 }
656 }
657 SerializeTask::MapEntries(peek_map) => {
658 let entries = peek_map.iter().collect::<Vec<_>>();
660 for (key_peek, value_peek) in entries.into_iter().rev() {
661 stack.push(SerializeTask::SerializeMapValue(value_peek));
662 stack.push(SerializeTask::SerializeMapKey(key_peek));
663 }
664 }
665
666 SerializeTask::SerializeFieldName(name) => {
668 serializer.serialize_field_name(name)?;
669 }
670 SerializeTask::SerializeMapKey(key_peek) => {
671 stack.push(SerializeTask::EndMapKey);
672 stack.push(SerializeTask::Value(key_peek, None));
673 serializer.begin_map_key()?;
674 }
675 SerializeTask::SerializeMapValue(value_peek) => {
676 stack.push(SerializeTask::EndMapValue);
677 stack.push(SerializeTask::Value(value_peek, None));
678 serializer.begin_map_value()?;
679 }
680
681 SerializeTask::EndObject => {
683 serializer.end_object()?;
684 }
685 SerializeTask::EndArray => {
686 serializer.end_array()?;
687 }
688 SerializeTask::EndMap => {
689 serializer.end_map()?;
690 }
691 SerializeTask::EndMapKey => {
692 serializer.end_map_key()?;
693 }
694 SerializeTask::EndMapValue => {
695 serializer.end_map_value()?;
696 }
697 SerializeTask::EndField => {
698 serializer.end_field()?;
699 }
700 }
701 }
702
703 Ok(())
705}
706
707pub trait Serialize<'a>: Facet<'a> {
711 fn serialize<'shape, S: Serializer<'shape>>(
713 &'a self,
714 serializer: &mut S,
715 ) -> Result<(), S::Error>;
716}
717
718impl<'a, T> Serialize<'a> for T
719where
720 T: Facet<'a>,
721{
722 fn serialize<'shape, S: Serializer<'shape>>(
724 &'a self,
725 serializer: &mut S,
726 ) -> Result<(), S::Error> {
727 let peek = Peek::new(self);
728 serialize_iterative(peek, serializer)
729 }
730}