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