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