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) =
385                                            cpeek.shape().vtable.sized().and_then(|v| (v.display)())
386                                        {
387                                            // Use display formatting if available
388                                            serializer
389                                                .serialize_str(&alloc::format!("{}", cpeek))?
390                                        } else {
391                                            panic!(
392                                                "Unsupported shape (no display): {}",
393                                                cpeek.shape()
394                                            )
395                                        }
396                                    }
397                                    _ => {
398                                        panic!(
399                                            "Unsupported shape (unsupported affinity): {}",
400                                            cpeek.shape()
401                                        )
402                                    }
403                                }
404                            }
405                        }
406                    }
407                    (Def::List(ld), _) => {
408                        if ld.t().is_type::<u8>() {
409                            // Special case for Vec<u8> - serialize as bytes
410                            if cpeek.shape().is_type::<Vec<u8>>() {
411                                serializer.serialize_bytes(cpeek.get::<Vec<u8>>().unwrap())?
412                            } else {
413                                // For other list types with u8 elements (like Bytes/BytesMut),
414                                // serialize as array
415                                let peek_list = cpeek.into_list_like().unwrap();
416                                stack.push(SerializeTask::Array {
417                                    items: peek_list.iter(),
418                                    first: true,
419                                });
420                            }
421                        } else {
422                            let peek_list = cpeek.into_list_like().unwrap();
423                            stack.push(SerializeTask::Array {
424                                items: peek_list.iter(),
425                                first: true,
426                            });
427                        }
428                    }
429                    (Def::Array(ad), _) => {
430                        if ad.t().is_type::<u8>() {
431                            let bytes: Vec<u8> = cpeek
432                                .into_list_like()
433                                .unwrap()
434                                .iter()
435                                .map(|p| *p.get::<u8>().unwrap())
436                                .collect();
437                            serializer.serialize_bytes(&bytes)?;
438                        } else {
439                            let peek_list = cpeek.into_list_like().unwrap();
440                            stack.push(SerializeTask::Array {
441                                items: peek_list.iter(),
442                                first: true,
443                            });
444                        }
445                    }
446                    (Def::Slice(sd), _) => {
447                        if sd.t().is_type::<u8>() {
448                            serializer.serialize_bytes(cpeek.get::<&[u8]>().unwrap())?
449                        } else {
450                            let peek_list = cpeek.into_list_like().unwrap();
451                            stack.push(SerializeTask::Array {
452                                items: peek_list.iter(),
453                                first: true,
454                            });
455                        }
456                    }
457                    (Def::Map(_), _) => {
458                        let peek_map = cpeek.into_map().unwrap();
459                        let len = peek_map.len();
460                        stack.push(SerializeTask::Map {
461                            entries: peek_map.iter(),
462                            first: true,
463                            len,
464                        });
465                    }
466                    (Def::Option(_), _) => {
467                        let opt = cpeek.into_option().unwrap();
468                        if let Some(inner_peek) = opt.value() {
469                            stack.push(SerializeTask::Value(inner_peek, None));
470                        } else {
471                            serializer.serialize_none()?;
472                        }
473                    }
474                    (Def::SmartPointer(_), _) => {
475                        // For smart pointers, we need to borrow the inner value and serialize it
476                        // This is similar to how transparent structs work - we serialize the inner value directly
477
478                        let sp = cpeek.into_smart_pointer().unwrap();
479                        if let Some(inner_peek) = sp.borrow_inner() {
480                            // Push the inner value to be serialized
481                            stack.push(SerializeTask::Value(inner_peek, None));
482                        } else {
483                            // The smart pointer doesn't support borrowing or has an opaque pointee
484                            // We can't serialize it
485                            todo!(
486                                "Smart pointer without borrow support or with opaque pointee cannot be serialized"
487                            );
488                        }
489                    }
490                    (_, Type::User(UserType::Struct(sd))) => {
491                        debug!("Serializing struct: shape={}", cpeek.shape(),);
492                        debug!(
493                            "  Struct details: kind={:?}, field_count={}",
494                            sd.kind,
495                            sd.fields.len()
496                        );
497
498                        match sd.kind {
499                            StructKind::Unit => {
500                                debug!("  Handling unit struct (no fields)");
501                                // Correctly handle unit struct type when encountered as a value
502                                serializer.serialize_unit()?;
503                            }
504                            StructKind::Tuple => {
505                                debug!("  Handling tuple with {} fields", sd.fields.len());
506                                let peek_struct = cpeek.into_struct().unwrap();
507                                let fields_iter = peek_struct.fields();
508                                debug!("  Serializing {} fields as tuple", sd.fields.len());
509
510                                stack.push(SerializeTask::Tuple {
511                                    items: fields_iter,
512                                    first: true,
513                                });
514                                trace!(
515                                    "  Pushed TupleFields to stack for tuple, will handle {} fields",
516                                    sd.fields.len()
517                                );
518                            }
519                            StructKind::TupleStruct => {
520                                debug!("  Handling tuple struct");
521                                let peek_struct = cpeek.into_struct().unwrap();
522                                let fields = peek_struct.fields_for_serialize().count();
523                                debug!("  Serializing {} fields as array", fields);
524
525                                stack.push(SerializeTask::TupleStruct {
526                                    items: peek_struct.fields_for_serialize(),
527                                    first: true,
528                                    len: fields,
529                                });
530                                trace!(
531                                    "  Pushed TupleStructFields to stack, will handle {} fields",
532                                    fields
533                                );
534                            }
535                            StructKind::Struct => {
536                                debug!("  Handling record struct");
537                                let peek_struct = cpeek.into_struct().unwrap();
538                                let fields = peek_struct.fields_for_serialize().count();
539                                debug!("  Serializing {} fields as object", fields);
540
541                                stack.push(SerializeTask::Object {
542                                    entries: peek_struct.fields_for_serialize(),
543                                    first: true,
544                                    len: fields,
545                                });
546                                trace!(
547                                    "  Pushed ObjectFields to stack, will handle {} fields",
548                                    fields
549                                );
550                            }
551                            _ => {
552                                unreachable!()
553                            }
554                        }
555                    }
556                    (_, Type::User(UserType::Enum(_))) => {
557                        let peek_enum = cpeek.into_enum().unwrap();
558                        let variant = peek_enum
559                            .active_variant()
560                            .expect("Failed to get active variant");
561                        let variant_index = peek_enum
562                            .variant_index()
563                            .expect("Failed to get variant index");
564                        trace!(
565                            "Active variant index is {}, variant is {:?}",
566                            variant_index, variant
567                        );
568                        let discriminant = variant
569                            .discriminant
570                            .map(|d| d as u64)
571                            .unwrap_or(variant_index as u64);
572                        serializer.start_enum_variant(discriminant)?;
573                        let flattened = maybe_field.map(|f| f.flattened).unwrap_or_default();
574
575                        if variant.data.fields.is_empty() {
576                            // Unit variant
577                            serializer.serialize_unit_variant(variant_index, variant.name)?;
578                        } else {
579                            if !flattened {
580                                // For now, treat all enum variants with data as objects
581                                serializer.start_object(Some(1))?;
582                                stack.push(SerializeTask::EndObject);
583
584                                // Serialize variant name as field name
585                                serializer.serialize_field_name(variant.name)?;
586                            }
587
588                            if variant_is_newtype_like(variant) {
589                                // Newtype variant - serialize the inner value directly
590                                let fields = peek_enum.fields_for_serialize().collect::<Vec<_>>();
591                                let (field, field_peek) = fields[0];
592                                // TODO: error if `skip_serialize` is set?
593                                stack.push(SerializeTask::Value(field_peek, Some(field)));
594                            } else if variant.data.kind == StructKind::Tuple
595                                || variant.data.kind == StructKind::TupleStruct
596                            {
597                                // Tuple variant - serialize as array
598                                let fields = peek_enum.fields_for_serialize().count();
599                                serializer.start_array(Some(fields))?;
600                                stack.push(SerializeTask::EndArray);
601
602                                // Push fields in reverse order for tuple variant
603                                let fields_for_serialize =
604                                    peek_enum.fields_for_serialize().collect::<Vec<_>>();
605                                for (field, field_peek) in fields_for_serialize.into_iter().rev() {
606                                    stack.push(SerializeTask::Value(field_peek, Some(field)));
607                                }
608                            } else {
609                                // Struct variant - serialize as object
610                                let fields = peek_enum.fields_for_serialize().count();
611                                serializer.start_object(Some(fields))?;
612                                stack.push(SerializeTask::EndObject);
613
614                                // Push fields in reverse order for struct variant
615                                let fields_for_serialize =
616                                    peek_enum.fields_for_serialize().collect::<Vec<_>>();
617                                for (field, field_peek) in fields_for_serialize.into_iter().rev() {
618                                    stack.push(SerializeTask::EndField);
619                                    stack.push(SerializeTask::Value(field_peek, Some(field)));
620                                    stack.push(SerializeTask::SerializeFieldName(field.name));
621                                }
622                            }
623                        }
624                    }
625                    (_, Type::Pointer(pointer_type)) => {
626                        // Handle pointer types using our new safe abstraction
627                        if let Some(str_value) = cpeek.as_str() {
628                            // We have a string value, serialize it
629                            serializer.serialize_str(str_value)?;
630                        } else if let Some(bytes) = cpeek.as_bytes() {
631                            // We have a byte slice, serialize it as bytes
632                            serializer.serialize_bytes(bytes)?;
633                        } else if let PointerType::Function(_) = pointer_type {
634                            // Serialize function pointers as units
635                            serializer.serialize_unit()?;
636                        } else {
637                            // Handle other pointer types with innermost_peek which is safe
638                            let innermost = cpeek.innermost_peek();
639                            if innermost.shape() != cpeek.shape() {
640                                // We got a different inner value, serialize it
641                                stack.push(SerializeTask::Value(innermost, None));
642                            } else {
643                                // Couldn't access inner value safely, fall back to unit
644                                serializer.serialize_unit()?;
645                            }
646                        }
647                    }
648                    _ => {
649                        // Default case for any other definitions
650                        debug!(
651                            "Unhandled type: {:?}, falling back to unit",
652                            cpeek.shape().ty
653                        );
654                        serializer.serialize_unit()?;
655                    }
656                }
657            }
658
659            SerializeTask::Object {
660                mut entries,
661                first,
662                len,
663            } => {
664                if first {
665                    serializer.start_object(Some(len))?;
666                }
667
668                let Some((field, value)) = entries.next() else {
669                    serializer.end_object()?;
670                    continue;
671                };
672
673                stack.push(SerializeTask::Object {
674                    entries,
675                    first: false,
676                    len,
677                });
678                stack.push(SerializeTask::EndField);
679                stack.push(SerializeTask::Value(value, Some(field)));
680                stack.push(SerializeTask::SerializeFieldName(field.name));
681            }
682            SerializeTask::Array { mut items, first } => {
683                if first {
684                    serializer.start_array(Some(items.len()))?;
685                }
686
687                let Some(value) = items.next() else {
688                    serializer.end_array()?;
689                    continue;
690                };
691
692                stack.push(SerializeTask::Array {
693                    items,
694                    first: false,
695                });
696                stack.push(SerializeTask::Value(value, None));
697            }
698            SerializeTask::Map {
699                mut entries,
700                first,
701                len,
702            } => {
703                if first {
704                    serializer.start_map(Some(len))?;
705                }
706
707                let Some((key, value)) = entries.next() else {
708                    serializer.end_map()?;
709                    continue;
710                };
711
712                stack.push(SerializeTask::Map {
713                    entries,
714                    first: false,
715                    len,
716                });
717                stack.push(SerializeTask::SerializeMapValue(value));
718                stack.push(SerializeTask::SerializeMapKey(key));
719            }
720            SerializeTask::TupleStruct {
721                mut items,
722                first,
723                len,
724            } => {
725                if first {
726                    serializer.start_array(Some(len))?;
727                }
728
729                let Some((field, value)) = items.next() else {
730                    serializer.end_array()?;
731                    continue;
732                };
733
734                stack.push(SerializeTask::TupleStruct {
735                    items,
736                    first: false,
737                    len,
738                });
739                stack.push(SerializeTask::Value(value, Some(field)));
740            }
741            SerializeTask::Tuple { mut items, first } => {
742                if first {
743                    serializer.start_array(Some(items.len()))?;
744                }
745
746                let Some((field, value)) = items.next() else {
747                    serializer.end_array()?;
748                    continue;
749                };
750
751                stack.push(SerializeTask::Tuple {
752                    items,
753                    first: false,
754                });
755                stack.push(SerializeTask::Value(value, Some(field)));
756            }
757
758            // --- Field name and map key/value handling ---
759            SerializeTask::SerializeFieldName(name) => {
760                serializer.serialize_field_name(name)?;
761            }
762            SerializeTask::SerializeMapKey(key_peek) => {
763                stack.push(SerializeTask::EndMapKey);
764                stack.push(SerializeTask::Value(key_peek, None));
765                serializer.begin_map_key()?;
766            }
767            SerializeTask::SerializeMapValue(value_peek) => {
768                stack.push(SerializeTask::EndMapValue);
769                stack.push(SerializeTask::Value(value_peek, None));
770                serializer.begin_map_value()?;
771            }
772
773            // --- End composite type tasks ---
774            SerializeTask::EndObject => {
775                serializer.end_object()?;
776            }
777            SerializeTask::EndArray => {
778                serializer.end_array()?;
779            }
780            SerializeTask::EndMapKey => {
781                serializer.end_map_key()?;
782            }
783            SerializeTask::EndMapValue => {
784                serializer.end_map_value()?;
785            }
786            SerializeTask::EndField => {
787                serializer.end_field()?;
788            }
789        }
790    }
791
792    // Successful completion
793    Ok(())
794}
795
796// --- Helper Trait for Ergonomics ---
797
798/// Extension trait to simplify calling the generic serializer.
799pub trait Serialize<'a>: Facet<'a> {
800    /// Serialize this value using the provided `Serializer`.
801    fn serialize<'shape, S: Serializer<'shape>>(
802        &'a self,
803        serializer: &mut S,
804    ) -> Result<(), S::Error>;
805}
806
807impl<'a, T> Serialize<'a> for T
808where
809    T: Facet<'a>,
810{
811    /// Serialize this value using the provided `Serializer`.
812    fn serialize<'shape, S: Serializer<'shape>>(
813        &'a self,
814        serializer: &mut S,
815    ) -> Result<(), S::Error> {
816        let peek = Peek::new(self);
817        serialize_iterative(peek, serializer)
818    }
819}