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