facet_serialize/
lib.rs

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#![forbid(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, ShapeAttribute, StructKind, Type, UserType,
15};
16use facet_reflect::{
17    FieldIter, FieldsForSerializeIter, HasFields, Peek, PeekListLikeIter, PeekMapIter, ScalarType,
18};
19use log::{debug, trace};
20
21mod debug_serializer;
22
23fn variant_is_newtype_like(variant: &facet_core::Variant) -> bool {
24    variant.data.kind == facet_core::StructKind::Tuple && variant.data.fields.len() == 1
25}
26
27// --- Serializer Trait Definition ---
28
29/// A trait for implementing format-specific serialization logic.
30/// The core iterative serializer uses this trait to output data.
31pub trait Serializer<'shape> {
32    /// The error type returned by serialization methods
33    type Error;
34
35    /// Serialize an unsigned 64-bit integer.
36    fn serialize_u64(&mut self, value: u64) -> Result<(), Self::Error>;
37
38    /// Serialize an unsigned 128-bit integer.
39    fn serialize_u128(&mut self, value: u128) -> Result<(), Self::Error>;
40
41    /// Serialize a signed 64-bit integer.
42    fn serialize_i64(&mut self, value: i64) -> Result<(), Self::Error>;
43
44    /// Serialize a signed 128-bit integer.
45    fn serialize_i128(&mut self, value: i128) -> Result<(), Self::Error>;
46
47    /// Serialize a double-precision floating-point value.
48    fn serialize_f64(&mut self, value: f64) -> Result<(), Self::Error>;
49
50    /// Serialize a boolean value.
51    fn serialize_bool(&mut self, value: bool) -> Result<(), Self::Error>;
52
53    /// Serialize a character.
54    fn serialize_char(&mut self, value: char) -> Result<(), Self::Error>;
55
56    /// Serialize a UTF-8 string slice.
57    fn serialize_str(&mut self, value: &str) -> Result<(), Self::Error>;
58
59    /// Serialize a raw byte slice.
60    fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error>;
61
62    // Special values
63
64    /// Serialize a `None` variant of an Option type.
65    fn serialize_none(&mut self) -> Result<(), Self::Error>;
66
67    /// Serialize a unit value `()`.
68    fn serialize_unit(&mut self) -> Result<(), Self::Error>;
69
70    // Enum specific values
71
72    /// Serialize a unit variant of an enum (no data).
73    ///
74    /// # Arguments
75    ///
76    /// * `variant_index` - The index of the variant.
77    /// * `variant_name` - The name of the variant.
78    fn serialize_unit_variant(
79        &mut self,
80        variant_index: usize,
81        variant_name: &'shape str,
82    ) -> Result<(), Self::Error>;
83
84    /// Begin serializing an object/map-like value.
85    ///
86    /// # Arguments
87    ///
88    /// * `len` - The number of fields, if known.
89    fn start_object(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
90
91    /// Serialize a field name (for objects and maps).
92    ///
93    /// # Arguments
94    ///
95    /// * `name` - The field or key name to serialize.
96    fn serialize_field_name(&mut self, name: &'shape str) -> Result<(), Self::Error>;
97
98    /// Begin serializing an array/sequence-like value.
99    ///
100    /// # Arguments
101    ///
102    /// * `len` - The number of elements, if known.
103    fn start_array(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
104
105    /// Begin serializing a map/dictionary-like value.
106    ///
107    /// # Arguments
108    ///
109    /// * `len` - The number of entries, if known.
110    fn start_map(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
111
112    /// Serialize an unsigned 8-bit integer.
113    #[inline(always)]
114    fn serialize_u8(&mut self, value: u8) -> Result<(), Self::Error> {
115        self.serialize_u64(value as u64)
116    }
117
118    /// Serialize an unsigned 16-bit integer.
119    #[inline(always)]
120    fn serialize_u16(&mut self, value: u16) -> Result<(), Self::Error> {
121        self.serialize_u64(value as u64)
122    }
123
124    /// Serialize an unsigned 32-bit integer.
125    #[inline(always)]
126    fn serialize_u32(&mut self, value: u32) -> Result<(), Self::Error> {
127        self.serialize_u64(value as u64)
128    }
129
130    /// Serialize a `usize` integer.
131    #[inline(always)]
132    fn serialize_usize(&mut self, value: usize) -> Result<(), Self::Error> {
133        // We assume `usize` will never be >64 bits
134        self.serialize_u64(value as u64)
135    }
136
137    /// Serialize a signed 8-bit integer.
138    #[inline(always)]
139    fn serialize_i8(&mut self, value: i8) -> Result<(), Self::Error> {
140        self.serialize_i64(value as i64)
141    }
142
143    /// Serialize a signed 16-bit integer.
144    #[inline(always)]
145    fn serialize_i16(&mut self, value: i16) -> Result<(), Self::Error> {
146        self.serialize_i64(value as i64)
147    }
148
149    /// Serialize a signed 32-bit integer.
150    #[inline(always)]
151    fn serialize_i32(&mut self, value: i32) -> Result<(), Self::Error> {
152        self.serialize_i64(value as i64)
153    }
154
155    /// Serialize an `isize` integer.
156    #[inline(always)]
157    fn serialize_isize(&mut self, value: isize) -> Result<(), Self::Error> {
158        // We assume `isize` will never be >64 bits
159        self.serialize_i64(value as i64)
160    }
161
162    /// Serialize a single-precision floating-point value.
163    #[inline(always)]
164    fn serialize_f32(&mut self, value: f32) -> Result<(), Self::Error> {
165        self.serialize_f64(value as f64)
166    }
167
168    /// Begin serializing a map key value.
169    #[inline(always)]
170    fn begin_map_key(&mut self) -> Result<(), Self::Error> {
171        Ok(())
172    }
173
174    /// Signal the end of serializing a map key value.
175    #[inline(always)]
176    fn end_map_key(&mut self) -> Result<(), Self::Error> {
177        Ok(())
178    }
179
180    /// Begin serializing a map value.
181    #[inline(always)]
182    fn begin_map_value(&mut self) -> Result<(), Self::Error> {
183        Ok(())
184    }
185
186    /// Signal the end of serializing a map value.
187    #[inline(always)]
188    fn end_map_value(&mut self) -> Result<(), Self::Error> {
189        Ok(())
190    }
191
192    /// Signal the end of serializing an object/map-like value.
193    #[inline(always)]
194    fn end_object(&mut self) -> Result<(), Self::Error> {
195        Ok(())
196    }
197
198    /// Signal the end of serializing an array/sequence-like value.
199    #[inline(always)]
200    fn end_array(&mut self) -> Result<(), Self::Error> {
201        Ok(())
202    }
203
204    /// Signal the end of serializing a map/dictionary-like value.
205    #[inline(always)]
206    fn end_map(&mut self) -> Result<(), Self::Error> {
207        Ok(())
208    }
209
210    /// Signal the end of serializing a field.
211    #[inline(always)]
212    fn end_field(&mut self) -> Result<(), Self::Error> {
213        Ok(())
214    }
215
216    /// Signal the start of an enum variant
217    #[inline(always)]
218    fn start_enum_variant(&mut self, discriminant: u64) -> Result<(), Self::Error> {
219        let _ = discriminant;
220        Ok(())
221    }
222}
223
224// --- Iterative Serialization Logic ---
225
226/// Task items for the serialization stack.
227enum SerializeTask<'mem, 'facet, 'shape> {
228    Value(Peek<'mem, 'facet, 'shape>, Option<Field<'shape>>),
229    Object {
230        entries: FieldsForSerializeIter<'mem, 'facet, 'shape>,
231        first: bool,
232        len: usize,
233    },
234    Array {
235        items: PeekListLikeIter<'mem, 'facet, 'shape>,
236        first: bool,
237    },
238    Map {
239        entries: PeekMapIter<'mem, 'facet, 'shape>,
240        first: bool,
241        len: usize,
242    },
243    TupleStruct {
244        items: FieldsForSerializeIter<'mem, 'facet, 'shape>,
245        first: bool,
246        len: usize,
247    },
248    Tuple {
249        items: FieldIter<'mem, 'facet, 'shape>,
250        first: bool,
251    },
252    // End markers
253    EndObject,
254    EndArray,
255    EndMapKey,
256    EndMapValue,
257    EndField,
258    // Field-related tasks
259    SerializeFieldName(&'shape str),
260    SerializeMapKey(Peek<'mem, 'facet, 'shape>),
261    SerializeMapValue(Peek<'mem, 'facet, 'shape>),
262}
263
264/// Serializes a `Peek` value using the provided `Serializer`.
265///
266/// This function uses an iterative approach with a stack to avoid recursion depth limits.
267pub fn serialize_iterative<'mem, 'facet, 'shape, S>(
268    peek: Peek<'mem, 'facet, 'shape>,
269    serializer: &mut S,
270) -> Result<(), S::Error>
271where
272    S: Serializer<'shape>,
273{
274    let mut stack = Vec::new();
275    stack.push(SerializeTask::Value(peek, None));
276
277    while let Some(task) = stack.pop() {
278        match task {
279            SerializeTask::Value(mut cpeek, maybe_field) => {
280                debug!("Serializing a value, shape is {}", cpeek.shape());
281
282                if cpeek
283                    .shape()
284                    .attributes
285                    .contains(&ShapeAttribute::Transparent)
286                {
287                    let old_shape = cpeek.shape();
288
289                    // then serialize the inner shape instead
290                    let ps = cpeek.into_struct().unwrap();
291                    cpeek = ps.field(0).unwrap();
292
293                    let new_shape = cpeek.shape();
294                    debug!(
295                        "{old_shape} is transparent, let's serialize the inner {new_shape} instead"
296                    );
297                }
298
299                debug!(
300                    "Matching def={:?}, ty={:?} for shape={}",
301                    cpeek.shape().def,
302                    cpeek.shape().ty,
303                    cpeek.shape()
304                );
305                match (cpeek.shape().def, cpeek.shape().ty) {
306                    (Def::Scalar(sd), _) => {
307                        let cpeek = cpeek.innermost_peek();
308
309                        // Dispatch to appropriate scalar serialization method based on type
310                        match cpeek.scalar_type() {
311                            Some(ScalarType::Unit) => serializer.serialize_unit()?,
312                            Some(ScalarType::Bool) => {
313                                serializer.serialize_bool(*cpeek.get::<bool>().unwrap())?
314                            }
315                            Some(ScalarType::Char) => {
316                                serializer.serialize_char(*cpeek.get::<char>().unwrap())?
317                            }
318
319                            // String types
320                            Some(ScalarType::Str) => {
321                                serializer.serialize_str(cpeek.get::<&str>().unwrap())?
322                            }
323                            Some(ScalarType::String) => {
324                                serializer.serialize_str(cpeek.get::<String>().unwrap())?
325                            }
326                            Some(ScalarType::CowStr) => serializer.serialize_str(
327                                cpeek.get::<alloc::borrow::Cow<'_, str>>().unwrap().as_ref(),
328                            )?,
329
330                            // Float types
331                            Some(ScalarType::F32) => {
332                                serializer.serialize_f32(*cpeek.get::<f32>().unwrap())?
333                            }
334                            Some(ScalarType::F64) => {
335                                serializer.serialize_f64(*cpeek.get::<f64>().unwrap())?
336                            }
337
338                            // Integer types
339                            Some(ScalarType::U8) => {
340                                serializer.serialize_u8(*cpeek.get::<u8>().unwrap())?
341                            }
342                            Some(ScalarType::U16) => {
343                                serializer.serialize_u16(*cpeek.get::<u16>().unwrap())?
344                            }
345                            Some(ScalarType::U32) => {
346                                serializer.serialize_u32(*cpeek.get::<u32>().unwrap())?
347                            }
348                            Some(ScalarType::U64) => {
349                                serializer.serialize_u64(*cpeek.get::<u64>().unwrap())?
350                            }
351                            Some(ScalarType::U128) => {
352                                serializer.serialize_u128(*cpeek.get::<u128>().unwrap())?
353                            }
354                            Some(ScalarType::USize) => {
355                                serializer.serialize_usize(*cpeek.get::<usize>().unwrap())?
356                            }
357                            Some(ScalarType::I8) => {
358                                serializer.serialize_i8(*cpeek.get::<i8>().unwrap())?
359                            }
360                            Some(ScalarType::I16) => {
361                                serializer.serialize_i16(*cpeek.get::<i16>().unwrap())?
362                            }
363                            Some(ScalarType::I32) => {
364                                serializer.serialize_i32(*cpeek.get::<i32>().unwrap())?
365                            }
366                            Some(ScalarType::I64) => {
367                                serializer.serialize_i64(*cpeek.get::<i64>().unwrap())?
368                            }
369                            Some(ScalarType::I128) => {
370                                serializer.serialize_i128(*cpeek.get::<i128>().unwrap())?
371                            }
372                            Some(ScalarType::ISize) => {
373                                serializer.serialize_isize(*cpeek.get::<isize>().unwrap())?
374                            }
375                            Some(unsupported) => {
376                                panic!("facet-serialize: unsupported scalar type: {unsupported:?}")
377                            }
378                            None => {
379                                match sd.affinity {
380                                    ScalarAffinity::Time(_)
381                                    | ScalarAffinity::Path(_)
382                                    | ScalarAffinity::ULID(_)
383                                    | ScalarAffinity::UUID(_) => {
384                                        if let Some(_display) = (cpeek.shape().vtable.display)() {
385                                            // Use display formatting if available
386                                            serializer
387                                                .serialize_str(&alloc::format!("{}", cpeek))?
388                                        } else {
389                                            panic!(
390                                                "Unsupported shape (no display): {}",
391                                                cpeek.shape()
392                                            )
393                                        }
394                                    }
395                                    _ => {
396                                        panic!(
397                                            "Unsupported shape (unsupported affinity): {}",
398                                            cpeek.shape()
399                                        )
400                                    }
401                                }
402                            }
403                        }
404                    }
405                    (Def::List(ld), _) => {
406                        if ld.t().is_type::<u8>() {
407                            // Special case for Vec<u8> - serialize as bytes
408                            if cpeek.shape().is_type::<Vec<u8>>() {
409                                serializer.serialize_bytes(cpeek.get::<Vec<u8>>().unwrap())?
410                            } else {
411                                // For other list types with u8 elements (like Bytes/BytesMut),
412                                // serialize as array
413                                let peek_list = cpeek.into_list_like().unwrap();
414                                stack.push(SerializeTask::Array {
415                                    items: peek_list.iter(),
416                                    first: true,
417                                });
418                            }
419                        } else {
420                            let peek_list = cpeek.into_list_like().unwrap();
421                            stack.push(SerializeTask::Array {
422                                items: peek_list.iter(),
423                                first: true,
424                            });
425                        }
426                    }
427                    (Def::Array(ad), _) => {
428                        if ad.t().is_type::<u8>() {
429                            let bytes: Vec<u8> = peek
430                                .into_list_like()
431                                .unwrap()
432                                .iter()
433                                .map(|p| *p.get::<u8>().unwrap())
434                                .collect();
435                            serializer.serialize_bytes(&bytes)?;
436                        } else {
437                            let peek_list = cpeek.into_list_like().unwrap();
438                            stack.push(SerializeTask::Array {
439                                items: peek_list.iter(),
440                                first: true,
441                            });
442                        }
443                    }
444                    (Def::Slice(sd), _) => {
445                        if sd.t().is_type::<u8>() {
446                            serializer.serialize_bytes(cpeek.get::<&[u8]>().unwrap())?
447                        } else {
448                            let peek_list = cpeek.into_list_like().unwrap();
449                            stack.push(SerializeTask::Array {
450                                items: peek_list.iter(),
451                                first: true,
452                            });
453                        }
454                    }
455                    (Def::Map(_), _) => {
456                        let peek_map = cpeek.into_map().unwrap();
457                        let len = peek_map.len();
458                        stack.push(SerializeTask::Map {
459                            entries: peek_map.iter(),
460                            first: true,
461                            len,
462                        });
463                    }
464                    (Def::Option(_), _) => {
465                        let opt = cpeek.into_option().unwrap();
466                        if let Some(inner_peek) = opt.value() {
467                            stack.push(SerializeTask::Value(inner_peek, None));
468                        } else {
469                            serializer.serialize_none()?;
470                        }
471                    }
472                    (Def::SmartPointer(_), _) => {
473                        // For smart pointers, we need to borrow the inner value and serialize it
474                        // This is similar to how transparent structs work - we serialize the inner value directly
475
476                        let sp = cpeek.into_smart_pointer().unwrap();
477                        if let Some(inner_peek) = sp.borrow_inner() {
478                            // Push the inner value to be serialized
479                            stack.push(SerializeTask::Value(inner_peek, None));
480                        } else {
481                            // The smart pointer doesn't support borrowing or has an opaque pointee
482                            // We can't serialize it
483                            todo!(
484                                "Smart pointer without borrow support or with opaque pointee cannot be serialized"
485                            );
486                        }
487                    }
488                    (_, Type::User(UserType::Struct(sd))) => {
489                        debug!("Serializing struct: shape={}", cpeek.shape(),);
490                        debug!(
491                            "  Struct details: kind={:?}, field_count={}",
492                            sd.kind,
493                            sd.fields.len()
494                        );
495
496                        match sd.kind {
497                            StructKind::Unit => {
498                                debug!("  Handling unit struct (no fields)");
499                                // Correctly handle unit struct type when encountered as a value
500                                serializer.serialize_unit()?;
501                            }
502                            StructKind::Tuple => {
503                                debug!("  Handling tuple with {} fields", sd.fields.len());
504                                let peek_struct = cpeek.into_struct().unwrap();
505                                let fields_iter = peek_struct.fields();
506                                debug!("  Serializing {} fields as tuple", sd.fields.len());
507
508                                stack.push(SerializeTask::Tuple {
509                                    items: fields_iter,
510                                    first: true,
511                                });
512                                trace!(
513                                    "  Pushed TupleFields to stack for tuple, will handle {} fields",
514                                    sd.fields.len()
515                                );
516                            }
517                            StructKind::TupleStruct => {
518                                debug!("  Handling tuple struct");
519                                let peek_struct = cpeek.into_struct().unwrap();
520                                let fields = peek_struct.fields_for_serialize().count();
521                                debug!("  Serializing {} fields as array", fields);
522
523                                stack.push(SerializeTask::TupleStruct {
524                                    items: peek_struct.fields_for_serialize(),
525                                    first: true,
526                                    len: fields,
527                                });
528                                trace!(
529                                    "  Pushed TupleStructFields to stack, will handle {} fields",
530                                    fields
531                                );
532                            }
533                            StructKind::Struct => {
534                                debug!("  Handling record struct");
535                                let peek_struct = cpeek.into_struct().unwrap();
536                                let fields = peek_struct.fields_for_serialize().count();
537                                debug!("  Serializing {} fields as object", fields);
538
539                                stack.push(SerializeTask::Object {
540                                    entries: peek_struct.fields_for_serialize(),
541                                    first: true,
542                                    len: fields,
543                                });
544                                trace!(
545                                    "  Pushed ObjectFields to stack, will handle {} fields",
546                                    fields
547                                );
548                            }
549                            _ => {
550                                unreachable!()
551                            }
552                        }
553                    }
554                    (_, Type::User(UserType::Enum(_))) => {
555                        let peek_enum = cpeek.into_enum().unwrap();
556                        let variant = peek_enum
557                            .active_variant()
558                            .expect("Failed to get active variant");
559                        let variant_index = peek_enum
560                            .variant_index()
561                            .expect("Failed to get variant index");
562                        trace!(
563                            "Active variant index is {}, variant is {:?}",
564                            variant_index, variant
565                        );
566                        let discriminant = variant
567                            .discriminant
568                            .map(|d| d as u64)
569                            .unwrap_or(variant_index as u64);
570                        serializer.start_enum_variant(discriminant)?;
571                        let flattened = maybe_field.map(|f| f.flattened).unwrap_or_default();
572
573                        if variant.data.fields.is_empty() {
574                            // Unit variant
575                            serializer.serialize_unit_variant(variant_index, variant.name)?;
576                        } else {
577                            if !flattened {
578                                // For now, treat all enum variants with data as objects
579                                serializer.start_object(Some(1))?;
580                                stack.push(SerializeTask::EndObject);
581
582                                // Serialize variant name as field name
583                                serializer.serialize_field_name(variant.name)?;
584                            }
585
586                            if variant_is_newtype_like(variant) {
587                                // Newtype variant - serialize the inner value directly
588                                let fields = peek_enum.fields_for_serialize().collect::<Vec<_>>();
589                                let (field, field_peek) = fields[0];
590                                // TODO: error if `skip_serialize` is set?
591                                stack.push(SerializeTask::Value(field_peek, Some(field)));
592                            } else if variant.data.kind == StructKind::Tuple
593                                || variant.data.kind == StructKind::TupleStruct
594                            {
595                                // Tuple variant - serialize as array
596                                let fields = peek_enum.fields_for_serialize().count();
597                                serializer.start_array(Some(fields))?;
598                                stack.push(SerializeTask::EndArray);
599
600                                // Push fields in reverse order for tuple variant
601                                let fields_for_serialize =
602                                    peek_enum.fields_for_serialize().collect::<Vec<_>>();
603                                for (field, field_peek) in fields_for_serialize.into_iter().rev() {
604                                    stack.push(SerializeTask::Value(field_peek, Some(field)));
605                                }
606                            } else {
607                                // Struct variant - serialize as object
608                                let fields = peek_enum.fields_for_serialize().count();
609                                serializer.start_object(Some(fields))?;
610                                stack.push(SerializeTask::EndObject);
611
612                                // Push fields in reverse order for struct variant
613                                let fields_for_serialize =
614                                    peek_enum.fields_for_serialize().collect::<Vec<_>>();
615                                for (field, field_peek) in fields_for_serialize.into_iter().rev() {
616                                    stack.push(SerializeTask::EndField);
617                                    stack.push(SerializeTask::Value(field_peek, Some(field)));
618                                    stack.push(SerializeTask::SerializeFieldName(field.name));
619                                }
620                            }
621                        }
622                    }
623                    (_, Type::Pointer(pointer_type)) => {
624                        // Handle pointer types using our new safe abstraction
625                        if let Some(str_value) = cpeek.as_str() {
626                            // We have a string value, serialize it
627                            serializer.serialize_str(str_value)?;
628                        } else if let Some(bytes) = cpeek.as_bytes() {
629                            // We have a byte slice, serialize it as bytes
630                            serializer.serialize_bytes(bytes)?;
631                        } else if let PointerType::Function(_) = pointer_type {
632                            // Serialize function pointers as units
633                            serializer.serialize_unit()?;
634                        } else {
635                            // Handle other pointer types with innermost_peek which is safe
636                            let innermost = cpeek.innermost_peek();
637                            if innermost.shape() != cpeek.shape() {
638                                // We got a different inner value, serialize it
639                                stack.push(SerializeTask::Value(innermost, None));
640                            } else {
641                                // Couldn't access inner value safely, fall back to unit
642                                serializer.serialize_unit()?;
643                            }
644                        }
645                    }
646                    _ => {
647                        // Default case for any other definitions
648                        debug!(
649                            "Unhandled type: {:?}, falling back to unit",
650                            cpeek.shape().ty
651                        );
652                        serializer.serialize_unit()?;
653                    }
654                }
655            }
656
657            SerializeTask::Object {
658                mut entries,
659                first,
660                len,
661            } => {
662                if first {
663                    serializer.start_object(Some(len))?;
664                }
665
666                let Some((field, value)) = entries.next() else {
667                    serializer.end_object()?;
668                    continue;
669                };
670
671                stack.push(SerializeTask::Object {
672                    entries,
673                    first: false,
674                    len,
675                });
676                stack.push(SerializeTask::EndField);
677                stack.push(SerializeTask::Value(value, Some(field)));
678                stack.push(SerializeTask::SerializeFieldName(field.name));
679            }
680            SerializeTask::Array { mut items, first } => {
681                if first {
682                    serializer.start_array(Some(items.len()))?;
683                }
684
685                let Some(value) = items.next() else {
686                    serializer.end_array()?;
687                    continue;
688                };
689
690                stack.push(SerializeTask::Array {
691                    items,
692                    first: false,
693                });
694                stack.push(SerializeTask::Value(value, None));
695            }
696            SerializeTask::Map {
697                mut entries,
698                first,
699                len,
700            } => {
701                if first {
702                    serializer.start_map(Some(len))?;
703                }
704
705                let Some((key, value)) = entries.next() else {
706                    serializer.end_map()?;
707                    continue;
708                };
709
710                stack.push(SerializeTask::Map {
711                    entries,
712                    first: false,
713                    len,
714                });
715                stack.push(SerializeTask::SerializeMapValue(value));
716                stack.push(SerializeTask::SerializeMapKey(key));
717            }
718            SerializeTask::TupleStruct {
719                mut items,
720                first,
721                len,
722            } => {
723                if first {
724                    serializer.start_array(Some(len))?;
725                }
726
727                let Some((field, value)) = items.next() else {
728                    serializer.end_array()?;
729                    continue;
730                };
731
732                stack.push(SerializeTask::TupleStruct {
733                    items,
734                    first: false,
735                    len,
736                });
737                stack.push(SerializeTask::Value(value, Some(field)));
738            }
739            SerializeTask::Tuple { mut items, first } => {
740                if first {
741                    serializer.start_array(Some(items.len()))?;
742                }
743
744                let Some((field, value)) = items.next() else {
745                    serializer.end_array()?;
746                    continue;
747                };
748
749                stack.push(SerializeTask::Tuple {
750                    items,
751                    first: false,
752                });
753                stack.push(SerializeTask::Value(value, Some(field)));
754            }
755
756            // --- Field name and map key/value handling ---
757            SerializeTask::SerializeFieldName(name) => {
758                serializer.serialize_field_name(name)?;
759            }
760            SerializeTask::SerializeMapKey(key_peek) => {
761                stack.push(SerializeTask::EndMapKey);
762                stack.push(SerializeTask::Value(key_peek, None));
763                serializer.begin_map_key()?;
764            }
765            SerializeTask::SerializeMapValue(value_peek) => {
766                stack.push(SerializeTask::EndMapValue);
767                stack.push(SerializeTask::Value(value_peek, None));
768                serializer.begin_map_value()?;
769            }
770
771            // --- End composite type tasks ---
772            SerializeTask::EndObject => {
773                serializer.end_object()?;
774            }
775            SerializeTask::EndArray => {
776                serializer.end_array()?;
777            }
778            SerializeTask::EndMapKey => {
779                serializer.end_map_key()?;
780            }
781            SerializeTask::EndMapValue => {
782                serializer.end_map_value()?;
783            }
784            SerializeTask::EndField => {
785                serializer.end_field()?;
786            }
787        }
788    }
789
790    // Successful completion
791    Ok(())
792}
793
794// --- Helper Trait for Ergonomics ---
795
796/// Extension trait to simplify calling the generic serializer.
797pub trait Serialize<'a>: Facet<'a> {
798    /// Serialize this value using the provided `Serializer`.
799    fn serialize<'shape, S: Serializer<'shape>>(
800        &'a self,
801        serializer: &mut S,
802    ) -> Result<(), S::Error>;
803}
804
805impl<'a, T> Serialize<'a> for T
806where
807    T: Facet<'a>,
808{
809    /// Serialize this value using the provided `Serializer`.
810    fn serialize<'shape, S: Serializer<'shape>>(
811        &'a self,
812        serializer: &mut S,
813    ) -> Result<(), S::Error> {
814        let peek = Peek::new(self);
815        serialize_iterative(peek, serializer)
816    }
817}