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