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 {
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: &'static 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: &'static 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> {
228 Value(Peek<'mem, 'facet>, Option<Field>),
229 EndObject,
231 EndArray,
232 EndMap,
233 EndMapKey,
234 EndMapValue,
235 EndField,
236 ObjectFields(PeekStruct<'mem, 'facet>),
238 ArrayItems(PeekListLike<'mem, 'facet>),
239 TupleStructFields(PeekStruct<'mem, 'facet>),
240 TupleFields(PeekTuple<'mem, 'facet>),
241 MapEntries(PeekMap<'mem, 'facet>),
242 SerializeFieldName(&'static str),
244 SerializeMapKey(Peek<'mem, 'facet>),
245 SerializeMapValue(Peek<'mem, 'facet>),
246}
247
248pub fn serialize_iterative<S>(peek: Peek<'_, '_>, serializer: &mut S) -> Result<(), S::Error>
252where
253 S: Serializer,
254{
255 let mut stack = Vec::new();
256 stack.push(SerializeTask::Value(peek, None));
257
258 while let Some(task) = stack.pop() {
259 match task {
260 SerializeTask::Value(mut cpeek, maybe_field) => {
261 debug!("Serializing a value, shape is {}", cpeek.shape());
262
263 if cpeek
264 .shape()
265 .attributes
266 .contains(&ShapeAttribute::Transparent)
267 {
268 let old_shape = cpeek.shape();
269
270 let ps = cpeek.into_struct().unwrap();
272 cpeek = ps.field(0).unwrap();
273
274 let new_shape = cpeek.shape();
275 debug!(
276 "{old_shape} is transparent, let's serialize the inner {new_shape} instead"
277 );
278 }
279
280 match (cpeek.shape().def, cpeek.shape().ty) {
281 (Def::Scalar(sd), _) => {
282 let cpeek = cpeek.innermost_peek();
283
284 match cpeek.scalar_type() {
286 Some(ScalarType::Unit) => serializer.serialize_unit()?,
287 Some(ScalarType::Bool) => {
288 serializer.serialize_bool(*cpeek.get::<bool>().unwrap())?
289 }
290 Some(ScalarType::Char) => {
291 serializer.serialize_char(*cpeek.get::<char>().unwrap())?
292 }
293
294 Some(ScalarType::Str) => {
296 serializer.serialize_str(cpeek.get::<&str>().unwrap())?
297 }
298 Some(ScalarType::String) => {
299 serializer.serialize_str(cpeek.get::<String>().unwrap())?
300 }
301 Some(ScalarType::CowStr) => serializer.serialize_str(
302 cpeek.get::<alloc::borrow::Cow<'_, str>>().unwrap().as_ref(),
303 )?,
304
305 Some(ScalarType::F32) => {
307 serializer.serialize_f32(*cpeek.get::<f32>().unwrap())?
308 }
309 Some(ScalarType::F64) => {
310 serializer.serialize_f64(*cpeek.get::<f64>().unwrap())?
311 }
312
313 Some(ScalarType::U8) => {
315 serializer.serialize_u8(*cpeek.get::<u8>().unwrap())?
316 }
317 Some(ScalarType::U16) => {
318 serializer.serialize_u16(*cpeek.get::<u16>().unwrap())?
319 }
320 Some(ScalarType::U32) => {
321 serializer.serialize_u32(*cpeek.get::<u32>().unwrap())?
322 }
323 Some(ScalarType::U64) => {
324 serializer.serialize_u64(*cpeek.get::<u64>().unwrap())?
325 }
326 Some(ScalarType::U128) => {
327 serializer.serialize_u128(*cpeek.get::<u128>().unwrap())?
328 }
329 Some(ScalarType::USize) => {
330 serializer.serialize_usize(*cpeek.get::<usize>().unwrap())?
331 }
332 Some(ScalarType::I8) => {
333 serializer.serialize_i8(*cpeek.get::<i8>().unwrap())?
334 }
335 Some(ScalarType::I16) => {
336 serializer.serialize_i16(*cpeek.get::<i16>().unwrap())?
337 }
338 Some(ScalarType::I32) => {
339 serializer.serialize_i32(*cpeek.get::<i32>().unwrap())?
340 }
341 Some(ScalarType::I64) => {
342 serializer.serialize_i64(*cpeek.get::<i64>().unwrap())?
343 }
344 Some(ScalarType::I128) => {
345 serializer.serialize_i128(*cpeek.get::<i128>().unwrap())?
346 }
347 Some(ScalarType::ISize) => {
348 serializer.serialize_isize(*cpeek.get::<isize>().unwrap())?
349 }
350 Some(unsupported) => {
351 panic!("facet-serialize: unsupported scalar type: {unsupported:?}")
352 }
353 None => {
354 match sd.affinity {
355 ScalarAffinity::Time(_)
356 | ScalarAffinity::Path(_)
357 | ScalarAffinity::ULID(_)
358 | ScalarAffinity::UUID(_) => {
359 if let Some(_display) = cpeek.shape().vtable.display {
360 serializer
362 .serialize_str(&alloc::format!("{}", cpeek))?
363 } else {
364 panic!(
365 "Unsupported shape (no display): {}",
366 cpeek.shape()
367 )
368 }
369 }
370 _ => {
371 panic!(
372 "Unsupported shape (unsupported affinity): {}",
373 cpeek.shape()
374 )
375 }
376 }
377 }
378 }
379 }
380 (Def::List(ld), _) => {
381 if ld.t().is_type::<u8>() {
382 serializer.serialize_bytes(cpeek.get::<Vec<u8>>().unwrap())?
383 } else {
384 let peek_list = cpeek.into_list_like().unwrap();
385 let len = peek_list.len();
386 serializer.start_array(Some(len))?;
387 stack.push(SerializeTask::EndArray);
388 stack.push(SerializeTask::ArrayItems(peek_list));
389 }
390 }
391 (Def::Array(ad), _) => {
392 if ad.t().is_type::<u8>() {
393 let bytes: Vec<u8> = peek
394 .into_list_like()
395 .unwrap()
396 .iter()
397 .map(|p| *p.get::<u8>().unwrap())
398 .collect();
399 serializer.serialize_bytes(&bytes)?;
400 } else {
401 let peek_list = cpeek.into_list_like().unwrap();
402 let len = peek_list.len();
403 serializer.start_array(Some(len))?;
404 stack.push(SerializeTask::EndArray);
405 stack.push(SerializeTask::ArrayItems(peek_list));
406 }
407 }
408 (Def::Slice(sd), _) => {
409 if sd.t().is_type::<u8>() {
410 serializer.serialize_bytes(cpeek.get::<&[u8]>().unwrap())?
411 } else {
412 let peek_list = cpeek.into_list_like().unwrap();
413 let len = peek_list.len();
414 serializer.start_array(Some(len))?;
415 stack.push(SerializeTask::EndArray);
416 stack.push(SerializeTask::ArrayItems(peek_list));
417 }
418 }
419 (Def::Map(_), _) => {
420 let peek_map = cpeek.into_map().unwrap();
421 let len = peek_map.len();
422 serializer.start_map(Some(len))?;
423 stack.push(SerializeTask::EndMap);
424 stack.push(SerializeTask::MapEntries(peek_map));
425 }
426 (Def::Option(_), _) => {
427 let opt = cpeek.into_option().unwrap();
428 if let Some(inner_peek) = opt.value() {
429 stack.push(SerializeTask::Value(inner_peek, None));
430 } else {
431 serializer.serialize_none()?;
432 }
433 }
434 (Def::SmartPointer(_), _) => {
435 let _sp = cpeek.into_smart_pointer().unwrap();
436 panic!("TODO: Implement serialization for smart pointers");
437 }
438 (_, Type::User(UserType::Struct(sd))) => {
439 debug!("Serializing struct: shape={}", cpeek.shape(),);
440 debug!(
441 " Struct details: kind={:?}, field_count={}",
442 sd.kind,
443 sd.fields.len()
444 );
445
446 match sd.kind {
447 StructKind::Unit => {
448 debug!(" Handling unit struct (no fields)");
449 serializer.serialize_unit()?;
451 }
452 StructKind::Tuple | StructKind::TupleStruct => {
453 debug!(" Handling tuple struct with {:?} kind", sd.kind);
454 let peek_struct = cpeek.into_struct().unwrap();
455 let fields = peek_struct.fields_for_serialize().count();
456 debug!(" Serializing {} fields as array", fields);
457
458 serializer.start_array(Some(fields))?;
459 stack.push(SerializeTask::EndArray);
460 stack.push(SerializeTask::TupleStructFields(peek_struct));
461 trace!(
462 " Pushed TupleStructFields to stack, will handle {} fields",
463 fields
464 );
465 }
466 StructKind::Struct => {
467 debug!(" Handling record struct");
468 let peek_struct = cpeek.into_struct().unwrap();
469 let fields = peek_struct.fields_for_serialize().count();
470 debug!(" Serializing {} fields as object", fields);
471
472 serializer.start_object(Some(fields))?;
473 stack.push(SerializeTask::EndObject);
474 stack.push(SerializeTask::ObjectFields(peek_struct));
475 trace!(
476 " Pushed ObjectFields to stack, will handle {} fields",
477 fields
478 );
479 }
480 _ => {
481 unreachable!()
482 }
483 }
484 }
485 (_, Type::Sequence(SequenceType::Tuple(_))) => {
486 debug!("Serializing tuple: shape={}", cpeek.shape(),);
487
488 if let Ok(peek_tuple) = cpeek.into_tuple() {
490 let count = peek_tuple.len();
491 debug!(" Tuple fields count: {}", count);
492
493 serializer.start_array(Some(count))?;
494 stack.push(SerializeTask::EndArray);
495 stack.push(SerializeTask::TupleFields(peek_tuple));
496 trace!(
497 " Pushed TupleFields to stack for tuple, will handle {} fields",
498 count
499 );
500 } else {
501 debug!(
504 " Could not convert to PeekTuple, falling back to list_like approach"
505 );
506
507 if let Ok(peek_list_like) = cpeek.into_list_like() {
508 let count = peek_list_like.len();
509 serializer.start_array(Some(count))?;
510 stack.push(SerializeTask::EndArray);
511 stack.push(SerializeTask::ArrayItems(peek_list_like));
512 trace!(" Pushed ArrayItems to stack for tuple serialization",);
513 } else {
514 debug!(
516 " Could not convert tuple to list-like either, using empty array"
517 );
518 serializer.start_array(Some(0))?;
519 stack.push(SerializeTask::EndArray);
520 trace!(" Warning: Tuple serialization fallback to empty array");
521 }
522 }
523 }
524 (_, Type::User(UserType::Enum(_))) => {
525 let peek_enum = cpeek.into_enum().unwrap();
526 let variant = peek_enum
527 .active_variant()
528 .expect("Failed to get active variant");
529 let variant_index = peek_enum
530 .variant_index()
531 .expect("Failed to get variant index");
532 trace!(
533 "Active variant index is {}, variant is {:?}",
534 variant_index, variant
535 );
536 let discriminant = variant
537 .discriminant
538 .map(|d| d as u64)
539 .unwrap_or(variant_index as u64);
540 serializer.start_enum_variant(discriminant)?;
541 let flattened = maybe_field.map(|f| f.flattened).unwrap_or_default();
542
543 if variant.data.fields.is_empty() {
544 serializer.serialize_unit_variant(variant_index, variant.name)?;
546 } else {
547 if !flattened {
548 serializer.start_object(Some(1))?;
550 stack.push(SerializeTask::EndObject);
551
552 serializer.serialize_field_name(variant.name)?;
554 }
555
556 if variant_is_newtype_like(variant) {
557 let fields = peek_enum.fields_for_serialize().collect::<Vec<_>>();
559 let (field, field_peek) = fields[0];
560 stack.push(SerializeTask::Value(field_peek, Some(field)));
562 } else if variant.data.kind == StructKind::Tuple
563 || variant.data.kind == StructKind::TupleStruct
564 {
565 let fields = peek_enum.fields_for_serialize().count();
567 serializer.start_array(Some(fields))?;
568 stack.push(SerializeTask::EndArray);
569
570 for (field, field_peek) in peek_enum.fields_for_serialize().rev() {
572 stack.push(SerializeTask::Value(field_peek, Some(field)));
573 }
574 } else {
575 let fields = peek_enum.fields_for_serialize().count();
577 serializer.start_object(Some(fields))?;
578 stack.push(SerializeTask::EndObject);
579
580 for (field, field_peek) in peek_enum.fields_for_serialize().rev() {
582 stack.push(SerializeTask::EndField);
583 stack.push(SerializeTask::Value(field_peek, Some(field)));
584 stack.push(SerializeTask::SerializeFieldName(field.name));
585 }
586 }
587 }
588 }
589 (_, Type::Pointer(pointer_type)) => {
590 if let Some(str_value) = cpeek.as_str() {
592 serializer.serialize_str(str_value)?;
594 } else if let PointerType::Function(_) = pointer_type {
595 serializer.serialize_unit()?;
597 } else {
598 let innermost = cpeek.innermost_peek();
600 if innermost.shape() != cpeek.shape() {
601 stack.push(SerializeTask::Value(innermost, None));
603 } else {
604 serializer.serialize_unit()?;
606 }
607 }
608 }
609 _ => {
610 debug!(
612 "Unhandled type: {:?}, falling back to unit",
613 cpeek.shape().ty
614 );
615 serializer.serialize_unit()?;
616 }
617 }
618 }
619
620 SerializeTask::ObjectFields(peek_struct) => {
622 for (field, field_peek) in peek_struct.fields_for_serialize().rev() {
624 stack.push(SerializeTask::EndField);
625 stack.push(SerializeTask::Value(field_peek, Some(field)));
626 stack.push(SerializeTask::SerializeFieldName(field.name));
627 }
628 }
629 SerializeTask::TupleStructFields(peek_struct) => {
630 for (field, field_peek) in peek_struct.fields_for_serialize().rev() {
632 stack.push(SerializeTask::Value(field_peek, Some(field)));
633 }
634 }
635 SerializeTask::TupleFields(peek_tuple) => {
636 for (_, field_peek) in peek_tuple.fields().rev() {
638 let innermost_peek = field_peek.innermost_peek();
641
642 stack.push(SerializeTask::Value(innermost_peek, None));
644 }
645 trace!(" Pushed {} tuple fields to stack", peek_tuple.len());
646 }
647 SerializeTask::ArrayItems(peek_list) => {
648 let items: Vec<_> = peek_list.iter().collect();
650 for item_peek in items.into_iter().rev() {
651 stack.push(SerializeTask::Value(item_peek, None));
652 }
653 }
654 SerializeTask::MapEntries(peek_map) => {
655 let entries = peek_map.iter().collect::<Vec<_>>();
657 for (key_peek, value_peek) in entries.into_iter().rev() {
658 stack.push(SerializeTask::SerializeMapValue(value_peek));
659 stack.push(SerializeTask::SerializeMapKey(key_peek));
660 }
661 }
662
663 SerializeTask::SerializeFieldName(name) => {
665 serializer.serialize_field_name(name)?;
666 }
667 SerializeTask::SerializeMapKey(key_peek) => {
668 stack.push(SerializeTask::EndMapKey);
669 stack.push(SerializeTask::Value(key_peek, None));
670 serializer.begin_map_key()?;
671 }
672 SerializeTask::SerializeMapValue(value_peek) => {
673 stack.push(SerializeTask::EndMapValue);
674 stack.push(SerializeTask::Value(value_peek, None));
675 serializer.begin_map_value()?;
676 }
677
678 SerializeTask::EndObject => {
680 serializer.end_object()?;
681 }
682 SerializeTask::EndArray => {
683 serializer.end_array()?;
684 }
685 SerializeTask::EndMap => {
686 serializer.end_map()?;
687 }
688 SerializeTask::EndMapKey => {
689 serializer.end_map_key()?;
690 }
691 SerializeTask::EndMapValue => {
692 serializer.end_map_value()?;
693 }
694 SerializeTask::EndField => {
695 serializer.end_field()?;
696 }
697 }
698 }
699
700 Ok(())
702}
703
704pub trait Serialize<'a>: Facet<'a> {
708 fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error>;
710}
711
712impl<'a, T> Serialize<'a> for T
713where
714 T: Facet<'a>,
715{
716 fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
718 let peek = Peek::new(self);
719 serialize_iterative(peek, serializer)
720 }
721}