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