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, SequenceType, ShapeAttribute, StructKind, Type, UserType,
15};
16use facet_reflect::{HasFields, Peek, PeekListLike, PeekMap, PeekStruct, PeekTuple, ScalarType};
17use log::{debug, trace};
18
19mod debug_serializer;
20
21fn variant_is_newtype_like(variant: &facet_core::Variant) -> bool {
22 variant.data.kind == facet_core::StructKind::Tuple && variant.data.fields.len() == 1
23}
24
25pub trait Serializer {
30 type Error;
32
33 fn serialize_u64(&mut self, value: u64) -> Result<(), Self::Error>;
35
36 fn serialize_u128(&mut self, value: u128) -> Result<(), Self::Error>;
38
39 fn serialize_i64(&mut self, value: i64) -> Result<(), Self::Error>;
41
42 fn serialize_i128(&mut self, value: i128) -> Result<(), Self::Error>;
44
45 fn serialize_f64(&mut self, value: f64) -> Result<(), Self::Error>;
47
48 fn serialize_bool(&mut self, value: bool) -> Result<(), Self::Error>;
50
51 fn serialize_char(&mut self, value: char) -> Result<(), Self::Error>;
53
54 fn serialize_str(&mut self, value: &str) -> Result<(), Self::Error>;
56
57 fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error>;
59
60 fn serialize_none(&mut self) -> Result<(), Self::Error>;
64
65 fn serialize_unit(&mut self) -> Result<(), Self::Error>;
67
68 fn serialize_unit_variant(
77 &mut self,
78 variant_index: usize,
79 variant_name: &'static str,
80 ) -> Result<(), Self::Error>;
81
82 fn start_object(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
88
89 fn serialize_field_name(&mut self, name: &'static str) -> Result<(), Self::Error>;
95
96 fn start_array(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
102
103 fn start_map(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
109
110 #[inline(always)]
112 fn serialize_u8(&mut self, value: u8) -> Result<(), Self::Error> {
113 self.serialize_u64(value as u64)
114 }
115
116 #[inline(always)]
118 fn serialize_u16(&mut self, value: u16) -> Result<(), Self::Error> {
119 self.serialize_u64(value as u64)
120 }
121
122 #[inline(always)]
124 fn serialize_u32(&mut self, value: u32) -> Result<(), Self::Error> {
125 self.serialize_u64(value as u64)
126 }
127
128 #[inline(always)]
130 fn serialize_usize(&mut self, value: usize) -> Result<(), Self::Error> {
131 self.serialize_u64(value as u64)
133 }
134
135 #[inline(always)]
137 fn serialize_i8(&mut self, value: i8) -> Result<(), Self::Error> {
138 self.serialize_i64(value as i64)
139 }
140
141 #[inline(always)]
143 fn serialize_i16(&mut self, value: i16) -> Result<(), Self::Error> {
144 self.serialize_i64(value as i64)
145 }
146
147 #[inline(always)]
149 fn serialize_i32(&mut self, value: i32) -> Result<(), Self::Error> {
150 self.serialize_i64(value as i64)
151 }
152
153 #[inline(always)]
155 fn serialize_isize(&mut self, value: isize) -> Result<(), Self::Error> {
156 self.serialize_i64(value as i64)
158 }
159
160 #[inline(always)]
162 fn serialize_f32(&mut self, value: f32) -> Result<(), Self::Error> {
163 self.serialize_f64(value as f64)
164 }
165
166 #[inline(always)]
168 fn begin_map_key(&mut self) -> Result<(), Self::Error> {
169 Ok(())
170 }
171
172 #[inline(always)]
174 fn end_map_key(&mut self) -> Result<(), Self::Error> {
175 Ok(())
176 }
177
178 #[inline(always)]
180 fn begin_map_value(&mut self) -> Result<(), Self::Error> {
181 Ok(())
182 }
183
184 #[inline(always)]
186 fn end_map_value(&mut self) -> Result<(), Self::Error> {
187 Ok(())
188 }
189
190 #[inline(always)]
192 fn end_object(&mut self) -> Result<(), Self::Error> {
193 Ok(())
194 }
195
196 #[inline(always)]
198 fn end_array(&mut self) -> Result<(), Self::Error> {
199 Ok(())
200 }
201
202 #[inline(always)]
204 fn end_map(&mut self) -> Result<(), Self::Error> {
205 Ok(())
206 }
207
208 #[inline(always)]
210 fn end_field(&mut self) -> Result<(), Self::Error> {
211 Ok(())
212 }
213}
214
215#[derive(Debug)]
219enum SerializeTask<'mem, 'facet> {
220 Value(Peek<'mem, 'facet>, Option<Field>),
221 EndObject,
223 EndArray,
224 EndMap,
225 EndMapKey,
226 EndMapValue,
227 EndField,
228 ObjectFields(PeekStruct<'mem, 'facet>),
230 ArrayItems(PeekListLike<'mem, 'facet>),
231 TupleStructFields(PeekStruct<'mem, 'facet>),
232 TupleFields(PeekTuple<'mem, 'facet>),
233 MapEntries(PeekMap<'mem, 'facet>),
234 SerializeFieldName(&'static str),
236 SerializeMapKey(Peek<'mem, 'facet>),
237 SerializeMapValue(Peek<'mem, 'facet>),
238}
239
240pub fn serialize_iterative<S>(peek: Peek<'_, '_>, serializer: &mut S) -> Result<(), S::Error>
244where
245 S: Serializer,
246{
247 let mut stack = Vec::new();
248 stack.push(SerializeTask::Value(peek, None));
249
250 while let Some(task) = stack.pop() {
251 match task {
252 SerializeTask::Value(mut cpeek, maybe_field) => {
253 debug!("Serializing a value, shape is {}", cpeek.shape(),);
254
255 if cpeek
256 .shape()
257 .attributes
258 .iter()
259 .any(|attr| *attr == ShapeAttribute::Transparent)
260 {
261 let old_shape = cpeek.shape();
262
263 let ps = cpeek.into_struct().unwrap();
265 cpeek = ps.field(0).unwrap();
266
267 let new_shape = cpeek.shape();
268 debug!(
269 "{old_shape} is transparent, let's serialize the inner {new_shape} instead"
270 );
271 }
272
273 match (cpeek.shape().def, cpeek.shape().ty) {
274 (Def::Scalar(_), _) => {
275 let cpeek = cpeek.innermost_peek();
276
277 match cpeek.scalar_type() {
279 Some(ScalarType::Unit) => serializer.serialize_unit()?,
280 Some(ScalarType::Bool) => {
281 serializer.serialize_bool(*cpeek.get::<bool>().unwrap())?
282 }
283 Some(ScalarType::Char) => {
284 serializer.serialize_char(*cpeek.get::<char>().unwrap())?
285 }
286
287 Some(ScalarType::Str) => {
289 serializer.serialize_str(cpeek.get::<&str>().unwrap())?
290 }
291 Some(ScalarType::String) => {
292 serializer.serialize_str(cpeek.get::<String>().unwrap())?
293 }
294 Some(ScalarType::CowStr) => serializer.serialize_str(
295 cpeek.get::<alloc::borrow::Cow<'_, str>>().unwrap().as_ref(),
296 )?,
297
298 Some(ScalarType::F32) => {
300 serializer.serialize_f32(*cpeek.get::<f32>().unwrap())?
301 }
302 Some(ScalarType::F64) => {
303 serializer.serialize_f64(*cpeek.get::<f64>().unwrap())?
304 }
305
306 Some(ScalarType::U8) => {
308 serializer.serialize_u8(*cpeek.get::<u8>().unwrap())?
309 }
310 Some(ScalarType::U16) => {
311 serializer.serialize_u16(*cpeek.get::<u16>().unwrap())?
312 }
313 Some(ScalarType::U32) => {
314 serializer.serialize_u32(*cpeek.get::<u32>().unwrap())?
315 }
316 Some(ScalarType::U64) => {
317 serializer.serialize_u64(*cpeek.get::<u64>().unwrap())?
318 }
319 Some(ScalarType::U128) => {
320 serializer.serialize_u128(*cpeek.get::<u128>().unwrap())?
321 }
322 Some(ScalarType::USize) => {
323 serializer.serialize_usize(*cpeek.get::<usize>().unwrap())?
324 }
325 Some(ScalarType::I8) => {
326 serializer.serialize_i8(*cpeek.get::<i8>().unwrap())?
327 }
328 Some(ScalarType::I16) => {
329 serializer.serialize_i16(*cpeek.get::<i16>().unwrap())?
330 }
331 Some(ScalarType::I32) => {
332 serializer.serialize_i32(*cpeek.get::<i32>().unwrap())?
333 }
334 Some(ScalarType::I64) => {
335 serializer.serialize_i64(*cpeek.get::<i64>().unwrap())?
336 }
337 Some(ScalarType::I128) => {
338 serializer.serialize_i128(*cpeek.get::<i128>().unwrap())?
339 }
340 Some(ScalarType::ISize) => {
341 serializer.serialize_isize(*cpeek.get::<isize>().unwrap())?
342 }
343 Some(unsupported) => panic!("Unsupported scalar type: {unsupported:?}"),
344 None => panic!("Unsupported shape: {}", cpeek.shape()),
345 }
346 }
347 (Def::List(_), _) | (Def::Array(_), _) | (Def::Slice(_), _) => {
348 let peek_list = cpeek.into_list_like().unwrap();
349 let len = peek_list.len();
350 serializer.start_array(Some(len))?;
351 stack.push(SerializeTask::EndArray);
352 stack.push(SerializeTask::ArrayItems(peek_list));
353 }
354 (Def::Map(_), _) => {
355 let peek_map = cpeek.into_map().unwrap();
356 let len = peek_map.len();
357 serializer.start_map(Some(len))?;
358 stack.push(SerializeTask::EndMap);
359 stack.push(SerializeTask::MapEntries(peek_map));
360 }
361 (Def::Option(_), _) => {
362 let opt = cpeek.into_option().unwrap();
363 if let Some(inner_peek) = opt.value() {
364 stack.push(SerializeTask::Value(inner_peek, None));
365 } else {
366 serializer.serialize_none()?;
367 }
368 }
369 (Def::SmartPointer(_), _) => {
370 let _sp = cpeek.into_smart_pointer().unwrap();
371 panic!("TODO: Implement serialization for smart pointers");
372 }
373 (_, Type::User(UserType::Struct(sd))) => {
374 debug!("Serializing struct: shape={}", cpeek.shape(),);
375 debug!(
376 " Struct details: kind={:?}, field_count={}",
377 sd.kind,
378 sd.fields.len()
379 );
380
381 match sd.kind {
382 StructKind::Unit => {
383 debug!(" Handling unit struct (no fields)");
384 serializer.serialize_unit()?;
386 }
387 StructKind::Tuple | StructKind::TupleStruct => {
388 debug!(" Handling tuple struct with {:?} kind", sd.kind);
389 let peek_struct = cpeek.into_struct().unwrap();
390 let fields = peek_struct.fields_for_serialize().count();
391 debug!(" Serializing {} fields as array", fields);
392
393 serializer.start_array(Some(fields))?;
394 stack.push(SerializeTask::EndArray);
395 stack.push(SerializeTask::TupleStructFields(peek_struct));
396 trace!(
397 " Pushed TupleStructFields to stack, will handle {} fields",
398 fields
399 );
400 }
401 StructKind::Struct => {
402 debug!(" Handling record struct");
403 let peek_struct = cpeek.into_struct().unwrap();
404 let fields = peek_struct.fields_for_serialize().count();
405 debug!(" Serializing {} fields as object", fields);
406
407 serializer.start_object(Some(fields))?;
408 stack.push(SerializeTask::EndObject);
409 stack.push(SerializeTask::ObjectFields(peek_struct));
410 trace!(
411 " Pushed ObjectFields to stack, will handle {} fields",
412 fields
413 );
414 }
415 _ => {
416 unreachable!()
417 }
418 }
419 }
420 (_, Type::Sequence(SequenceType::Tuple(_))) => {
421 debug!("Serializing tuple: shape={}", cpeek.shape(),);
422
423 if let Ok(peek_tuple) = cpeek.into_tuple() {
425 let count = peek_tuple.len();
426 debug!(" Tuple fields count: {}", count);
427
428 serializer.start_array(Some(count))?;
429 stack.push(SerializeTask::EndArray);
430 stack.push(SerializeTask::TupleFields(peek_tuple));
431 trace!(
432 " Pushed TupleFields to stack for tuple, will handle {} fields",
433 count
434 );
435 } else {
436 debug!(
439 " Could not convert to PeekTuple, falling back to list_like approach"
440 );
441
442 if let Ok(peek_list_like) = cpeek.into_list_like() {
443 let count = peek_list_like.len();
444 serializer.start_array(Some(count))?;
445 stack.push(SerializeTask::EndArray);
446 stack.push(SerializeTask::ArrayItems(peek_list_like));
447 trace!(" Pushed ArrayItems to stack for tuple serialization",);
448 } else {
449 debug!(
451 " Could not convert tuple to list-like either, using empty array"
452 );
453 serializer.start_array(Some(0))?;
454 stack.push(SerializeTask::EndArray);
455 trace!(" Warning: Tuple serialization fallback to empty array");
456 }
457 }
458 }
459 (_, Type::User(UserType::Enum(_))) => {
460 let peek_enum = cpeek.into_enum().unwrap();
461 let variant = peek_enum
462 .active_variant()
463 .expect("Failed to get active variant");
464 let variant_index = peek_enum
465 .variant_index()
466 .expect("Failed to get variant index");
467 trace!(
468 "Active variant index is {}, variant is {:?}",
469 variant_index, variant
470 );
471 let flattened = maybe_field.map(|f| f.flattened).unwrap_or_default();
472
473 if variant.data.fields.is_empty() {
474 serializer.serialize_unit_variant(variant_index, variant.name)?;
476 } else {
477 if !flattened {
478 serializer.start_object(Some(1))?;
480 stack.push(SerializeTask::EndObject);
481
482 serializer.serialize_field_name(variant.name)?;
484 }
485
486 if variant_is_newtype_like(variant) {
487 let fields = peek_enum.fields_for_serialize().collect::<Vec<_>>();
489 let (field, field_peek) = fields[0];
490 stack.push(SerializeTask::Value(field_peek, Some(field)));
492 } else if variant.data.kind == StructKind::Tuple
493 || variant.data.kind == StructKind::TupleStruct
494 {
495 let fields = peek_enum.fields_for_serialize().count();
497 serializer.start_array(Some(fields))?;
498 stack.push(SerializeTask::EndArray);
499
500 for (field, field_peek) in peek_enum.fields_for_serialize().rev() {
502 stack.push(SerializeTask::Value(field_peek, Some(field)));
503 }
504 } else {
505 let fields = peek_enum.fields_for_serialize().count();
507 serializer.start_object(Some(fields))?;
508 stack.push(SerializeTask::EndObject);
509
510 for (field, field_peek) in peek_enum.fields_for_serialize().rev() {
512 stack.push(SerializeTask::EndField);
513 stack.push(SerializeTask::Value(field_peek, Some(field)));
514 stack.push(SerializeTask::SerializeFieldName(field.name));
515 }
516 }
517 }
518 }
519 (_, Type::Pointer(pointer_type)) => {
520 if let Some(str_value) = cpeek.as_str() {
522 serializer.serialize_str(str_value)?;
524 } else if let PointerType::Function(_) = pointer_type {
525 serializer.serialize_unit()?;
527 } else {
528 let innermost = cpeek.innermost_peek();
530 if innermost.shape() != cpeek.shape() {
531 stack.push(SerializeTask::Value(innermost, None));
533 } else {
534 serializer.serialize_unit()?;
536 }
537 }
538 }
539 _ => {
540 debug!(
542 "Unhandled type: {:?}, falling back to unit",
543 cpeek.shape().ty
544 );
545 serializer.serialize_unit()?;
546 }
547 }
548 }
549
550 SerializeTask::ObjectFields(peek_struct) => {
552 for (field, field_peek) in peek_struct.fields_for_serialize().rev() {
554 stack.push(SerializeTask::EndField);
555 stack.push(SerializeTask::Value(field_peek, Some(field)));
556 stack.push(SerializeTask::SerializeFieldName(field.name));
557 }
558 }
559 SerializeTask::TupleStructFields(peek_struct) => {
560 for (field, field_peek) in peek_struct.fields_for_serialize().rev() {
562 stack.push(SerializeTask::Value(field_peek, Some(field)));
563 }
564 }
565 SerializeTask::TupleFields(peek_tuple) => {
566 for (_, field_peek) in peek_tuple.fields().rev() {
568 let innermost_peek = field_peek.innermost_peek();
571
572 stack.push(SerializeTask::Value(innermost_peek, None));
574 }
575 trace!(" Pushed {} tuple fields to stack", peek_tuple.len());
576 }
577 SerializeTask::ArrayItems(peek_list) => {
578 let items: Vec<_> = peek_list.iter().collect();
580 for item_peek in items.into_iter().rev() {
581 stack.push(SerializeTask::Value(item_peek, None));
582 }
583 }
584 SerializeTask::MapEntries(peek_map) => {
585 let entries = peek_map.iter().collect::<Vec<_>>();
587 for (key_peek, value_peek) in entries.into_iter().rev() {
588 stack.push(SerializeTask::SerializeMapValue(value_peek));
589 stack.push(SerializeTask::SerializeMapKey(key_peek));
590 }
591 }
592
593 SerializeTask::SerializeFieldName(name) => {
595 serializer.serialize_field_name(name)?;
596 }
597 SerializeTask::SerializeMapKey(key_peek) => {
598 stack.push(SerializeTask::EndMapKey);
599 stack.push(SerializeTask::Value(key_peek, None));
600 serializer.begin_map_key()?;
601 }
602 SerializeTask::SerializeMapValue(value_peek) => {
603 stack.push(SerializeTask::EndMapValue);
604 stack.push(SerializeTask::Value(value_peek, None));
605 serializer.begin_map_value()?;
606 }
607
608 SerializeTask::EndObject => {
610 serializer.end_object()?;
611 }
612 SerializeTask::EndArray => {
613 serializer.end_array()?;
614 }
615 SerializeTask::EndMap => {
616 serializer.end_map()?;
617 }
618 SerializeTask::EndMapKey => {
619 serializer.end_map_key()?;
620 }
621 SerializeTask::EndMapValue => {
622 serializer.end_map_value()?;
623 }
624 SerializeTask::EndField => {
625 serializer.end_field()?;
626 }
627 }
628 }
629
630 Ok(())
632}
633
634pub trait Serialize<'a>: Facet<'a> {
638 fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error>;
640}
641
642impl<'a, T> Serialize<'a> for T
643where
644 T: Facet<'a>,
645{
646 fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
648 let peek = Peek::new(self);
649 serialize_iterative(peek, serializer)
650 }
651}