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