fory_core/serializer/
core.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use crate::error::Error;
19use crate::meta::FieldInfo;
20use crate::resolver::context::{ReadContext, WriteContext};
21use crate::resolver::type_resolver::TypeInfo;
22use crate::serializer::{bool, struct_};
23use crate::types::{RefFlag, TypeId};
24use crate::TypeResolver;
25use std::any::Any;
26use std::rc::Rc;
27
28/// Trait for creating default values during Fory deserialization.
29///
30/// `ForyDefault` is similar to Rust's standard `Default` trait but specifically designed
31/// for Fory's serialization framework. It provides a way to create "null" or default
32/// values when deserializing optional or nullable types.
33///
34/// # Why not use `Default`?
35///
36/// We can't add a blanket implementation `impl<T: Default> ForyDefault for T` because
37/// it would conflict with potential future implementations in upstream crates. For example,
38/// the standard library might add `impl Default for Rc<dyn Any>` in the future, which would
39/// cause a trait coherence conflict.
40///
41/// # When to implement
42///
43/// You should implement `ForyDefault` when:
44/// - Creating custom types that can be serialized with Fory
45/// - Your type needs to support nullable/optional representations
46/// - You want to define what the "null" or "default" value means for deserialization
47///
48/// # Examples
49///
50/// ```
51/// use fory_core::ForyDefault;
52///
53/// #[derive(Debug, PartialEq)]
54/// struct Point {
55///     x: i32,
56///     y: i32,
57/// }
58///
59/// impl ForyDefault for Point {
60///     fn fory_default() -> Self {
61///         Point { x: 0, y: 0 }
62///     }
63/// }
64///
65/// let default_point = Point::fory_default();
66/// assert_eq!(default_point, Point { x: 0, y: 0 });
67/// ```
68///
69/// For types that already implement `Default`, you can simply delegate:
70///
71/// ```
72/// use fory_core::ForyDefault;
73///
74/// #[derive(Default)]
75/// struct Config {
76///     timeout: u32,
77///     retries: u32,
78/// }
79///
80/// impl ForyDefault for Config {
81///     fn fory_default() -> Self {
82///         Default::default()
83///     }
84/// }
85/// ```
86pub trait ForyDefault: Sized {
87    /// Creates a default value for this type.
88    ///
89    /// This is used by Fory when deserializing null values or when a default
90    /// instance is needed during the deserialization process.
91    fn fory_default() -> Self;
92}
93
94// We can't add blanket impl for all T: Default because it conflicts with other impls.
95// For example, upstream crates may add a new impl of trait `std::default::Default` for
96// type `std::rc::Rc<(dyn std::any::Any + 'static)>` in future versions.
97// impl<T: Default + Sized> ForyDefault for T {
98//     fn fory_default() -> Self {
99//         Default::default()
100//     }
101// }
102
103/// Core trait for Fory serialization and deserialization.
104///
105/// `Serializer` is the primary trait that enables types to be serialized and deserialized
106/// using Fory's high-performance cross-language protocol. All types that can be serialized
107/// with Fory must implement this trait, either manually or via the `#[derive(ForyObject)]` macro.
108///
109/// # Architecture Overview
110///
111/// Fory's serialization consists of three main phases:
112///
113/// 1. **Reference tracking** (optional): Writes/reads null/not-null/ref flags for handling
114///    shared references and circular references
115/// 2. **Type information** (optional): Writes/reads type metadata for polymorphic types
116/// 3. **Data serialization**: Writes/reads the actual data payload
117///
118/// # Method Categories
119///
120/// ## Methods Users Must Implement (for custom serialization logic)
121///
122/// - [`fory_write_data`]: Core method to serialize your type's data
123/// - [`fory_read_data`]: Core method to deserialize your type's data
124/// - [`fory_type_id_dyn`]: Return runtime type ID for the instance
125/// - [`as_any`]: Downcast support for dynamic dispatch
126///
127/// ## Methods Implemented by Fory (override only if needed)
128///
129/// Most methods have default implementations suitable for common types:
130///
131/// - [`fory_write`]: Entry point for serialization (handles ref/type info)
132/// - [`fory_read`]: Entry point for deserialization (handles ref/type info)
133/// - [`fory_write_type_info`]: Write type metadata
134/// - [`fory_read_type_info`]: Read type metadata
135/// - [`fory_write_data_generic`]: Write data with generics support (for collections)
136/// - [`fory_read_with_type_info`]: Deserialize with pre-read type info
137///
138/// ## Type Query Methods
139///
140/// These provide compile-time and runtime type information:
141///
142/// - [`fory_static_type_id`]: Static type ID (defaults to TypeId::EXT for user types)
143/// - [`fory_get_type_id`]: Get registered type ID from TypeResolver
144/// - [`fory_concrete_type_id`]: Get Rust's std::any::TypeId
145/// - [`fory_is_option`]: Check if type is `Option<T>`
146/// - [`fory_is_none`]: Check if instance is None (for Option types)
147/// - [`fory_is_polymorphic`]: Check if type supports polymorphism
148/// - [`fory_is_shared_ref`]: Check if type is Rc/Arc
149/// - [`fory_reserved_space`]: Hint for buffer pre-allocation
150///
151/// # Typical Usage Pattern
152///
153/// For types that need custom serialization logic (EXT types), you only need to implement four methods:
154///
155/// ```rust,ignore
156/// impl Serializer for MyType {
157///     fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
158///         // Write your type's fields
159///     }
160///
161///     fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
162///         // Read your type's fields
163///     }
164///
165///     fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<u32, Error> {
166///         Self::fory_get_type_id(type_resolver)
167///     }
168///
169///     fn as_any(&self) -> &dyn Any {
170///         self
171///     }
172/// }
173/// ```
174///
175/// # Derive Macro
176///
177/// For struct types, you can use the `#[derive(ForyObject)]` macro instead of implementing manually:
178///
179/// ```rust,ignore
180/// #[derive(ForyObject)]
181/// struct Point {
182///     x: f64,
183///     y: f64,
184/// }
185/// ```
186///
187/// # See Also
188///
189/// - [`ForyDefault`]: Trait for creating default values during deserialization
190/// - [`StructSerializer`]: Extended trait for struct-specific serialization
191///
192/// [`fory_write_data`]: Serializer::fory_write_data
193/// [`fory_read_data`]: Serializer::fory_read_data
194/// [`fory_write`]: Serializer::fory_write
195/// [`fory_read`]: Serializer::fory_read
196/// [`fory_write_type_info`]: Serializer::fory_write_type_info
197/// [`fory_read_type_info`]: Serializer::fory_read_type_info
198/// [`fory_write_data_generic`]: Serializer::fory_write_data_generic
199/// [`fory_read_with_type_info`]: Serializer::fory_read_with_type_info
200/// [`fory_type_id_dyn`]: Serializer::fory_type_id_dyn
201/// [`as_any`]: Serializer::as_any
202/// [`fory_static_type_id`]: Serializer::fory_static_type_id
203/// [`fory_get_type_id`]: Serializer::fory_get_type_id
204/// [`fory_concrete_type_id`]: Serializer::fory_concrete_type_id
205/// [`fory_is_option`]: Serializer::fory_is_option
206/// [`fory_is_none`]: Serializer::fory_is_none
207/// [`fory_is_polymorphic`]: Serializer::fory_is_polymorphic
208/// [`fory_is_shared_ref`]: Serializer::fory_is_shared_ref
209/// [`fory_reserved_space`]: Serializer::fory_reserved_space
210pub trait Serializer: 'static {
211    /// Entry point for serialization.
212    ///
213    /// This method orchestrates the complete serialization process, handling reference tracking,
214    /// type information, and delegating to [`fory_write_data`] for the actual data serialization.
215    ///
216    /// # Parameters
217    ///
218    /// * `write_ref_info` - When `true`, WRITES reference flag (null/not-null/ref). When `false`, SKIPS writing ref flag.
219    /// * `write_type_info` - When `true`, WRITES type information. When `false`, SKIPS writing type info.
220    /// * `has_generics` - Indicates if the type has generic parameters (used for collection meta).
221    ///
222    /// # Default Implementation
223    ///
224    /// The default implementation handles standard non-nullable types:
225    ///
226    /// 1. If `write_ref_info` is true, writes `RefFlag::NotNullValue`
227    /// 2. If `write_type_info` is true, calls [`fory_write_type_info`]
228    /// 3. Calls [`fory_write_data_generic`] to write the actual data
229    ///
230    /// # When to Override
231    ///
232    /// You should override this method for:
233    ///
234    /// - **Option types**: Need to write `RefFlag::Null` for None values
235    /// - **Reference types** (Rc/Arc/Weak): Need custom reference handling
236    /// - **Polymorphic types**: Need to write actual runtime type instead of static type
237    ///
238    /// For regular types (structs, primitives, collections), the default implementation is sufficient.
239    ///
240    /// # Implementation Notes
241    ///
242    /// - This method is implemented by Fory for all built-in types
243    /// - User types with custom serialization typically don't need to override this
244    /// - Focus on implementing [`fory_write_data`] instead
245    ///
246    /// [`fory_write_data`]: Serializer::fory_write_data
247    /// [`fory_write_type_info`]: Serializer::fory_write_type_info
248    /// [`fory_write_data_generic`]: Serializer::fory_write_data_generic
249    #[inline(always)]
250    fn fory_write(
251        &self,
252        context: &mut WriteContext,
253        write_ref_info: bool,
254        write_type_info: bool,
255        has_generics: bool,
256    ) -> Result<(), Error>
257    where
258        Self: Sized,
259    {
260        if write_ref_info {
261            // skip check option/pointer, the Serializer for such types will override `fory_write`.
262            context.writer.write_i8(RefFlag::NotNullValue as i8);
263        }
264        if write_type_info {
265            // Serializer for dynamic types should override `fory_write` to write actual typeinfo.
266            Self::fory_write_type_info(context)?;
267        }
268        self.fory_write_data_generic(context, has_generics)
269    }
270
271    /// Write data with generic type parameter support.
272    ///
273    /// This method is primarily used by collection types (Vec, HashMap, etc.) that need to
274    /// write generic type information for their elements. For most types, this simply
275    /// delegates to [`fory_write_data`].
276    ///
277    /// # Parameters
278    ///
279    /// * `context` - Write context containing the buffer and type resolver
280    /// * `has_generics` - Indicates if the type has generic parameters that need metadata
281    ///
282    /// # Default Implementation
283    ///
284    /// The default implementation ignores `has_generics` and forwards to [`fory_write_data`]:
285    ///
286    /// ```rust,ignore
287    /// fn fory_write_data_generic(&self, context: &mut WriteContext, has_generics: bool) -> Result<(), Error> {
288    ///     self.fory_write_data(context)
289    /// }
290    /// ```
291    ///
292    /// # When to Override
293    ///
294    /// Override this method for:
295    ///
296    /// - **Collection types** (Vec, HashMap, HashSet, etc.): Need to write element/key/value type metadata
297    /// - **Generic containers**: Any type that contains type parameters requiring runtime metadata
298    ///
299    /// For non-generic types (primitives, simple structs), use the default implementation.
300    ///
301    /// # Implementation Notes
302    ///
303    /// - Implemented by Fory for all collection types
304    /// - User types with custom serialization for non-generic types don't need to override
305    /// - Focus on implementing [`fory_write_data`] for custom types
306    ///
307    /// [`fory_write_data`]: Serializer::fory_write_data
308    #[inline(always)]
309    #[allow(unused_variables)]
310    fn fory_write_data_generic(
311        &self,
312        context: &mut WriteContext,
313        has_generics: bool,
314    ) -> Result<(), Error> {
315        self.fory_write_data(context)
316    }
317
318    /// **[USER IMPLEMENTATION REQUIRED]** Serialize the type's data to the buffer.
319    ///
320    /// This is the core serialization method that you must implement for custom types.
321    /// It should write all the type's fields and data to the buffer using the provided context.
322    ///
323    /// # Parameters
324    ///
325    /// * `context` - Write context providing:
326    ///   - `context.writer`: Buffer to write binary data
327    ///   - `context.type_resolver`: Registry of type information
328    ///   - `context.ref_resolver`: Resolver for shared/circular references (if enabled)
329    ///
330    /// # Writing Data
331    ///
332    /// Use methods on `context.writer` to write primitive types:
333    ///
334    /// - `write_i8()`, `write_i16()`, `write_i32()`, `write_i64()`: Signed integers
335    /// - `write_u8()`, `write_u16()`, `write_u32()`, `write_u64()`: Unsigned integers
336    /// - `write_f32()`, `write_f64()`: Floating point numbers
337    /// - `write_bool()`: Boolean values
338    /// - `write_bytes()`: Raw byte arrays
339    ///
340    /// For nested types that implement `Serializer`, call their serialization:
341    ///
342    /// ```rust,ignore
343    /// // For types that implement Serializer
344    /// self.nested_field.fory_write(context, false, false, false)?;
345    /// ```
346    ///
347    /// # Examples
348    ///
349    /// ## Simple struct with primitive fields
350    ///
351    /// ```rust
352    /// use fory_core::{Serializer, ForyDefault};
353    /// use fory_core::resolver::context::WriteContext;
354    /// use fory_core::error::Error;
355    /// use std::any::Any;
356    ///
357    /// struct Point {
358    ///     x: f64,
359    ///     y: f64,
360    /// }
361    ///
362    /// impl ForyDefault for Point {
363    ///     fn fory_default() -> Self {
364    ///         Point { x: 0.0, y: 0.0 }
365    ///     }
366    /// }
367    ///
368    /// impl Serializer for Point {
369    ///     fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
370    ///         // Write each field in order
371    ///         context.writer.write_f64(self.x);
372    ///         context.writer.write_f64(self.y);
373    ///         Ok(())
374    ///     }
375    ///
376    ///     fn fory_read_data(context: &mut fory_core::resolver::context::ReadContext) -> Result<Self, Error>
377    ///     where
378    ///         Self: Sized + fory_core::ForyDefault,
379    ///     {
380    ///         let x = context.reader.read_f64()?;
381    ///         let y = context.reader.read_f64()?;
382    ///         Ok(Point { x, y })
383    ///     }
384    ///
385    ///     fn fory_type_id_dyn(&self, type_resolver: &fory_core::TypeResolver) -> Result<u32, Error> {
386    ///         Self::fory_get_type_id(type_resolver)
387    ///     }
388    ///
389    ///     fn as_any(&self) -> &dyn Any {
390    ///         self
391    ///     }
392    /// }
393    /// ```
394    ///
395    /// ## Struct with nested serializable types
396    ///
397    /// ```rust
398    /// use fory_core::{Serializer, ForyDefault};
399    /// use fory_core::resolver::context::WriteContext;
400    /// use fory_core::error::Error;
401    /// use std::any::Any;
402    ///
403    /// struct Person {
404    ///     name: String,
405    ///     age: u32,
406    ///     scores: Vec<i32>,
407    /// }
408    ///
409    /// impl ForyDefault for Person {
410    ///     fn fory_default() -> Self {
411    ///         Person {
412    ///             name: String::new(),
413    ///             age: 0,
414    ///             scores: Vec::new(),
415    ///         }
416    ///     }
417    /// }
418    ///
419    /// impl Serializer for Person {
420    ///     fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
421    ///         // Write nested types using their Serializer implementations
422    ///         self.name.fory_write(context, false, false, false)?;
423    ///         context.writer.write_u32(self.age);
424    ///         self.scores.fory_write(context, false, false, true)?; // has_generics=true for Vec
425    ///         Ok(())
426    ///     }
427    ///
428    ///     fn fory_read_data(context: &mut fory_core::resolver::context::ReadContext) -> Result<Self, Error>
429    ///     where
430    ///         Self: Sized + fory_core::ForyDefault,
431    ///     {
432    ///         let name = String::fory_read(context, false, false)?;
433    ///         let age = context.reader.read_u32()?;
434    ///         let scores = Vec::<i32>::fory_read(context, false, false)?;
435    ///         Ok(Person { name, age, scores })
436    ///     }
437    ///
438    ///     fn fory_type_id_dyn(&self, type_resolver: &fory_core::TypeResolver) -> Result<u32, Error> {
439    ///         Self::fory_get_type_id(type_resolver)
440    ///     }
441    ///
442    ///     fn as_any(&self) -> &dyn Any {
443    ///         self
444    ///     }
445    /// }
446    /// ```
447    ///
448    /// # Implementation Guidelines
449    ///
450    /// 1. **Field order matters**: Write fields in a consistent order; read them in the same order
451    /// 2. **No metadata here**: Don't write type info or ref flags; that's handled by [`fory_write`]
452    /// 3. **Use Serializer for nested types**: Leverage existing implementations for standard types
453    /// 4. **Error handling**: Propagate errors with `?`; don't swallow them
454    /// 5. **Performance**: Minimize allocations; write directly to the buffer
455    ///
456    /// # Common Patterns
457    ///
458    /// ```rust,ignore
459    /// // Writing primitives directly
460    /// context.writer.write_i32(self.count);
461    ///
462    /// // Writing nested Serializer types
463    /// self.nested.fory_write(context, false, false, false)?;
464    ///
465    /// // Writing collections with generics
466    /// self.items.fory_write(context, false, false, true)?;
467    ///
468    /// // Writing optional types
469    /// self.optional.fory_write(context, true, false, false)?; // write_ref_info=true
470    /// ```
471    ///
472    /// # See Also
473    ///
474    /// - [`fory_read_data`]: Corresponding deserialization method
475    /// - [`fory_write`]: High-level serialization entry point
476    /// - [`WriteContext`]: Context providing buffer and resolver access
477    ///
478    /// [`fory_write`]: Serializer::fory_write
479    /// [`fory_read_data`]: Serializer::fory_read_data
480    fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error>;
481
482    /// Write type metadata to the buffer.
483    ///
484    /// This method writes type information that allows Fory to identify and deserialize
485    /// the type correctly, especially for polymorphic scenarios.
486    ///
487    /// # Default Implementation
488    ///
489    /// The default implementation writes:
490    ///
491    /// 1. Static type ID from [`fory_static_type_id`]
492    /// 2. Rust's `std::any::TypeId` for runtime type identification
493    ///
494    /// ```rust,ignore
495    /// fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
496    ///     let rs_type_id = std::any::TypeId::of::<Self>();
497    ///     context.write_any_typeinfo(Self::fory_static_type_id() as u32, rs_type_id)?;
498    ///     Ok(())
499    /// }
500    /// ```
501    ///
502    /// # When to Override
503    ///
504    /// Override this method for:
505    ///
506    /// - **Built-in types**: Fory's internal types override for optimized performance
507    /// - **Custom type ID schemes**: If you need special type identification logic
508    ///
509    /// For user types with custom serialization, the default implementation is typically sufficient.
510    ///
511    /// # Implementation Notes
512    ///
513    /// - Called by [`fory_write`] when `write_type_info` is true
514    /// - Implemented by Fory for all built-in types with optimized paths
515    /// - User types with custom serialization rarely need to override this
516    ///
517    /// [`fory_static_type_id`]: Serializer::fory_static_type_id
518    /// [`fory_write`]: Serializer::fory_write
519    #[inline(always)]
520    fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error>
521    where
522        Self: Sized,
523    {
524        // Serializer for internal types should overwrite this method for faster performance.
525        let rs_type_id = std::any::TypeId::of::<Self>();
526        context.write_any_typeinfo(Self::fory_static_type_id() as u32, rs_type_id)?;
527        Ok(())
528    }
529
530    /// Entry point for deserialization.
531    ///
532    /// This method orchestrates the complete deserialization process, handling reference tracking,
533    /// type information validation, and delegating to [`fory_read_data`] for the actual data deserialization.
534    ///
535    /// # Parameters
536    ///
537    /// * `read_ref_info` - When `true`, READS reference flag from buffer. When `false`, SKIPS reading ref flag.
538    /// * `read_type_info` - When `true`, READS type information from buffer. When `false`, SKIPS reading type info.
539    ///
540    /// # Type Requirements
541    ///
542    /// This method requires `Self: Sized + ForyDefault` because:
543    ///
544    /// - **Sized**: Need to construct concrete instances
545    /// - **ForyDefault**: Need to create default/null values for optional types
546    ///
547    /// # Default Implementation
548    ///
549    /// The default implementation handles standard non-nullable types:
550    ///
551    /// 1. If `read_ref_info` is true:
552    ///    - Reads ref flag from buffer
553    ///    - Returns `ForyDefault::fory_default()` for null values
554    ///    - Handles ref tracking for shared references
555    /// 2. If `read_type_info` is true, calls [`fory_read_type_info`]
556    /// 3. Calls [`fory_read_data`] to read the actual data
557    ///
558    /// # When to Override
559    ///
560    /// Override this method for:
561    ///
562    /// - **Option types**: Need custom null handling logic
563    /// - **Reference types** (Rc/Arc/Weak): Need custom ref tracking
564    /// - **Polymorphic types**: Need to dispatch based on actual runtime type
565    ///
566    /// For regular types (structs, primitives, collections), the default implementation is sufficient.
567    ///
568    /// # Implementation Notes
569    ///
570    /// - Unlike [`fory_write`], this doesn't need `has_generics` parameter
571    /// - Generic metadata is already in the buffer and parsed during read
572    /// - Implemented by Fory for all built-in types
573    /// - User types with custom serialization typically don't need to override this
574    /// - Focus on implementing [`fory_read_data`] instead
575    ///
576    /// [`fory_read_data`]: Serializer::fory_read_data
577    /// [`fory_read_type_info`]: Serializer::fory_read_type_info
578    /// [`fory_write`]: Serializer::fory_write
579    #[inline(always)]
580    fn fory_read(
581        context: &mut ReadContext,
582        read_ref_info: bool,
583        read_type_info: bool,
584    ) -> Result<Self, Error>
585    where
586        Self: Sized + ForyDefault,
587    {
588        if read_ref_info {
589            let ref_flag = context.reader.read_i8()?;
590            match ref_flag {
591                flag if flag == RefFlag::Null as i8 => Ok(Self::fory_default()),
592                flag if flag == RefFlag::NotNullValue as i8 || flag == RefFlag::RefValue as i8 => {
593                    if read_type_info {
594                        Self::fory_read_type_info(context)?;
595                    }
596                    Self::fory_read_data(context)
597                }
598                flag if flag == RefFlag::Ref as i8 => {
599                    Err(Error::invalid_ref("Invalid ref, current type is not a ref"))
600                }
601                other => Err(Error::invalid_data(format!("Unknown ref flag: {}", other))),
602            }
603        } else {
604            if read_type_info {
605                Self::fory_read_type_info(context)?;
606            }
607            Self::fory_read_data(context)
608        }
609    }
610
611    /// Deserialize with pre-read type information.
612    ///
613    /// This method is used when type information has already been read from the buffer
614    /// and needs to be passed to the deserialization logic. This is common in polymorphic
615    /// deserialization scenarios where the runtime type differs from the static type.
616    ///
617    /// # Parameters
618    ///
619    /// * `read_ref_info` - When `true`, READS reference flag from buffer. When `false`, SKIPS reading ref flag.
620    /// * `type_info` - Type information that has already been read ahead. DO NOT read type info again from buffer.
621    ///
622    /// # Important
623    ///
624    /// **DO NOT** read type info from the buffer in this method. The `type_info` parameter
625    /// contains the already-read type metadata. Reading it again will cause buffer position errors.
626    ///
627    /// # Default Implementation
628    ///
629    /// The default implementation ignores the provided `type_info` and delegates to [`fory_read`]:
630    ///
631    /// ```rust,ignore
632    /// fn fory_read_with_type_info(
633    ///     context: &mut ReadContext,
634    ///     read_ref_info: bool,
635    ///     type_info: Rc<TypeInfo>,
636    /// ) -> Result<Self, Error> {
637    ///     // Ignore type_info since static type matches
638    ///     Self::fory_read(context, read_ref_info, false) // read_type_info=false
639    /// }
640    /// ```
641    ///
642    /// This works for:
643    ///
644    /// - **Monomorphic types**: Static type matches runtime type
645    /// - **Final types**: Types that don't participate in polymorphism
646    /// - **User-defined types**: Types registered with Fory that don't require polymorphism
647    ///
648    /// # When to Override
649    ///
650    /// Override this method for:
651    ///
652    /// - **Trait objects** (dyn Trait): Need to dispatch to concrete implementation based on type_info
653    /// - **Reference types with polymorphic targets**: Rc\<dyn Trait\>, Arc\<dyn Trait\>
654    /// - **Custom polymorphic types**: Types with runtime type variation
655    ///
656    /// # Implementation Notes
657    ///
658    /// - Called by Fory's polymorphic deserialization infrastructure
659    /// - The `type_info` parameter contains the actual runtime type ID
660    /// - Implemented by Fory for all polymorphic types
661    /// - User types with custom serialization rarely need to override this
662    ///
663    /// [`fory_read`]: Serializer::fory_read
664    #[inline(always)]
665    #[allow(unused_variables)]
666    fn fory_read_with_type_info(
667        context: &mut ReadContext,
668        read_ref_info: bool,
669        type_info: Rc<TypeInfo>,
670    ) -> Result<Self, Error>
671    where
672        Self: Sized + ForyDefault,
673    {
674        // Default implementation ignores the provided typeinfo because the static type matches.
675        // Honor the supplied `read_ref_info` flag so callers can control whether ref metadata is present.
676        Self::fory_read(context, read_ref_info, false)
677    }
678
679    /// **[USER IMPLEMENTATION REQUIRED]** Deserialize the type's data from the buffer.
680    ///
681    /// This is the core deserialization method that you must implement for custom types.
682    /// It should read all the type's fields and data from the buffer in the same order
683    /// they were written by [`fory_write_data`].
684    ///
685    /// # Parameters
686    ///
687    /// * `context` - Read context providing:
688    ///   - `context.reader`: Buffer to read binary data
689    ///   - `context.type_resolver`: Registry of type information
690    ///   - `context.ref_resolver`: Resolver for shared/circular references (if enabled)
691    ///
692    /// # Type Requirements
693    ///
694    /// Requires `Self: Sized + ForyDefault`:
695    ///
696    /// - **Sized**: Need to construct concrete instances on the stack
697    /// - **ForyDefault**: Need to create default/null values for optional fields
698    ///
699    /// # Reading Data
700    ///
701    /// Use methods on `context.reader` to read primitive types:
702    ///
703    /// - `read_i8()`, `read_i16()`, `read_i32()`, `read_i64()`: Signed integers
704    /// - `read_u8()`, `read_u16()`, `read_u32()`, `read_u64()`: Unsigned integers
705    /// - `read_f32()`, `read_f64()`: Floating point numbers
706    /// - `read_bool()`: Boolean values
707    /// - `read_bytes()`: Raw byte arrays
708    ///
709    /// For nested types that implement `Serializer`, call their deserialization:
710    ///
711    /// ```rust,ignore
712    /// // For types that implement Serializer
713    /// let field = T::fory_read(context, false, false)?;
714    /// ```
715    ///
716    /// # Examples
717    ///
718    /// ## Simple struct with primitive fields
719    ///
720    /// ```rust
721    /// use fory_core::{Serializer, ForyDefault};
722    /// use fory_core::resolver::context::{ReadContext, WriteContext};
723    /// use fory_core::error::Error;
724    /// use std::any::Any;
725    ///
726    /// #[derive(Debug, PartialEq)]
727    /// struct Point {
728    ///     x: f64,
729    ///     y: f64,
730    /// }
731    ///
732    /// impl ForyDefault for Point {
733    ///     fn fory_default() -> Self {
734    ///         Point { x: 0.0, y: 0.0 }
735    ///     }
736    /// }
737    ///
738    /// impl Serializer for Point {
739    ///     fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
740    ///         context.writer.write_f64(self.x);
741    ///         context.writer.write_f64(self.y);
742    ///         Ok(())
743    ///     }
744    ///
745    ///     fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error>
746    ///     where
747    ///         Self: Sized + ForyDefault,
748    ///     {
749    ///         // Read fields in the same order as written
750    ///         let x = context.reader.read_f64()?;
751    ///         let y = context.reader.read_f64()?;
752    ///         Ok(Point { x, y })
753    ///     }
754    ///
755    ///     fn fory_type_id_dyn(&self, type_resolver: &fory_core::TypeResolver) -> Result<u32, Error> {
756    ///         Self::fory_get_type_id(type_resolver)
757    ///     }
758    ///
759    ///     fn as_any(&self) -> &dyn Any {
760    ///         self
761    ///     }
762    /// }
763    /// ```
764    ///
765    /// ## Struct with nested serializable types
766    ///
767    /// ```rust
768    /// use fory_core::{Serializer, ForyDefault};
769    /// use fory_core::resolver::context::{ReadContext, WriteContext};
770    /// use fory_core::error::Error;
771    /// use std::any::Any;
772    ///
773    /// #[derive(Debug, PartialEq)]
774    /// struct Person {
775    ///     name: String,
776    ///     age: u32,
777    ///     scores: Vec<i32>,
778    /// }
779    ///
780    /// impl ForyDefault for Person {
781    ///     fn fory_default() -> Self {
782    ///         Person {
783    ///             name: String::new(),
784    ///             age: 0,
785    ///             scores: Vec::new(),
786    ///         }
787    ///     }
788    /// }
789    ///
790    /// impl Serializer for Person {
791    ///     fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
792    ///         self.name.fory_write(context, false, false, false)?;
793    ///         context.writer.write_u32(self.age);
794    ///         self.scores.fory_write(context, false, false, true)?;
795    ///         Ok(())
796    ///     }
797    ///
798    ///     fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error>
799    ///     where
800    ///         Self: Sized + ForyDefault,
801    ///     {
802    ///         // Read nested types in the same order as written
803    ///         let name = String::fory_read(context, false, false)?;
804    ///         let age = context.reader.read_u32()?;
805    ///         let scores = Vec::<i32>::fory_read(context, false, false)?;
806    ///         Ok(Person { name, age, scores })
807    ///     }
808    ///
809    ///     fn fory_type_id_dyn(&self, type_resolver: &fory_core::TypeResolver) -> Result<u32, Error> {
810    ///         Self::fory_get_type_id(type_resolver)
811    ///     }
812    ///
813    ///     fn as_any(&self) -> &dyn Any {
814    ///         self
815    ///     }
816    /// }
817    /// ```
818    ///
819    /// ## Struct with optional fields
820    ///
821    /// ```rust,ignore
822    /// use fory_core::{Serializer, ForyDefault};
823    /// use fory_core::resolver::context::{ReadContext, WriteContext};
824    /// use fory_core::error::Error;
825    /// use std::any::Any;
826    ///
827    /// #[derive(Debug, PartialEq)]
828    /// struct Config {
829    ///     name: String,
830    ///     timeout: Option<u32>,
831    /// }
832    ///
833    /// impl ForyDefault for Config {
834    ///     fn fory_default() -> Self {
835    ///         Config {
836    ///             name: String::new(),
837    ///             timeout: None,
838    ///         }
839    ///     }
840    /// }
841    ///
842    /// impl Serializer for Config {
843    ///     fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
844    ///         self.name.fory_write(context, false, false, false)?;
845    ///         // Option needs ref tracking to handle None
846    ///         self.timeout.fory_write(context, true, false, false)?;
847    ///         Ok(())
848    ///     }
849    ///
850    ///     fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error>
851    ///     where
852    ///         Self: Sized + ForyDefault,
853    ///     {
854    ///         let name = String::fory_read(context, false, false)?;
855    ///         // Read Option with ref tracking enabled
856    ///         let timeout = Option::<u32>::fory_read(context, true, false)?;
857    ///         Ok(Config { name, timeout })
858    ///     }
859    ///
860    ///     fn fory_type_id_dyn(&self, type_resolver: &fory_core::TypeResolver) -> Result<u32, Error> {
861    ///         Self::fory_get_type_id(type_resolver)
862    ///     }
863    ///
864    ///     fn as_any(&self) -> &dyn Any {
865    ///         self
866    ///     }
867    /// }
868    /// ```
869    ///
870    /// # Implementation Guidelines
871    ///
872    /// 1. **Mirror write order**: Read fields in the exact same order as [`fory_write_data`] writes them
873    /// 2. **Error propagation**: Use `?` operator to propagate read errors
874    /// 3. **No metadata reading**: Don't read ref flags or type info; that's handled by [`fory_read`]
875    /// 4. **Use Serializer for nested types**: Leverage existing implementations
876    /// 5. **Handle errors gracefully**: Return descriptive errors for invalid data
877    ///
878    /// # Common Patterns
879    ///
880    /// ```rust,ignore
881    /// // Reading primitives
882    /// let count = context.reader.read_i32()?;
883    ///
884    /// // Reading nested Serializer types
885    /// let nested = T::fory_read(context, false, false)?;
886    ///
887    /// // Reading collections
888    /// let items = Vec::<T>::fory_read(context, false, false)?;
889    ///
890    /// // Reading optional types
891    /// let optional = Option::<T>::fory_read(context, true, false)?;
892    /// ```
893    ///
894    /// # Error Handling
895    ///
896    /// Return errors for:
897    ///
898    /// - **Buffer underflow**: Not enough data to read
899    /// - **Invalid data**: Data doesn't match expected format
900    /// - **Version mismatch**: Incompatible serialization format
901    ///
902    /// ```rust,ignore
903    /// if value > MAX_ALLOWED {
904    ///     return Err(Error::invalid_data(format!("Value {} exceeds maximum", value)));
905    /// }
906    /// ```
907    ///
908    /// # See Also
909    ///
910    /// - [`fory_write_data`]: Corresponding serialization method
911    /// - [`fory_read`]: High-level deserialization entry point
912    /// - [`ForyDefault`]: Trait for creating default values
913    /// - [`ReadContext`]: Context providing buffer and resolver access
914    ///
915    /// [`fory_write_data`]: Serializer::fory_write_data
916    /// [`fory_read`]: Serializer::fory_read
917    fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error>
918    where
919        Self: Sized + ForyDefault;
920
921    /// Read and validate type metadata from the buffer.
922    ///
923    /// This method reads type information to verify that the data in the buffer
924    /// matches the expected type. It's the counterpart to [`fory_write_type_info`].
925    ///
926    /// # Default Implementation
927    ///
928    /// The default implementation reads and validates the type info:
929    ///
930    /// ```rust,ignore
931    /// fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
932    ///     context.read_any_typeinfo()?;
933    ///     Ok(())
934    /// }
935    /// ```
936    ///
937    /// # When to Override
938    ///
939    /// Override this method for:
940    ///
941    /// - **Built-in types**: Fory's internal types override for optimized performance
942    /// - **Custom validation logic**: If you need special type checking
943    ///
944    /// For user types with custom serialization, the default implementation is typically sufficient.
945    ///
946    /// # Implementation Notes
947    ///
948    /// - Called by [`fory_read`] when `read_type_info` is true
949    /// - Implemented by Fory for all built-in types with optimized paths
950    /// - User types with custom serialization rarely need to override this
951    ///
952    /// [`fory_write_type_info`]: Serializer::fory_write_type_info
953    /// [`fory_read`]: Serializer::fory_read
954    #[inline(always)]
955    fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error>
956    where
957        Self: Sized,
958    {
959        // Serializer for internal types should overwrite this method for faster performance.
960        context.read_any_typeinfo()?;
961        Ok(())
962    }
963
964    /// Check if this type is `Option<T>`.
965    ///
966    /// # Returns
967    ///
968    /// - `true` if the type is `Option<T>`
969    /// - `false` for all other types (default)
970    ///
971    /// # Implementation Notes
972    ///
973    /// - Implemented by Fory for `Option<T>` to return `true`
974    /// - User types with custom serialization should not override this
975    /// - Used internally for null handling optimization
976    #[inline(always)]
977    fn fory_is_option() -> bool
978    where
979        Self: Sized,
980    {
981        false
982    }
983
984    /// Check if this instance represents a `None` value.
985    ///
986    /// This method is used for runtime checking of optional values.
987    ///
988    /// # Returns
989    ///
990    /// - `true` if the instance is `Option::None`
991    /// - `false` for all other values (default)
992    ///
993    /// # Implementation Notes
994    ///
995    /// - Implemented by Fory for `Option<T>` to check None state
996    /// - User types with custom serialization should not override this
997    /// - Used with [`fory_is_option`] for null handling
998    ///
999    /// [`fory_is_option`]: Serializer::fory_is_option
1000    #[inline(always)]
1001    fn fory_is_none(&self) -> bool {
1002        false
1003    }
1004
1005    /// Check if this type supports polymorphic serialization.
1006    ///
1007    /// Polymorphic types can have different runtime types than their static type,
1008    /// requiring special handling during serialization and deserialization.
1009    ///
1010    /// # Returns
1011    ///
1012    /// - `true` if the type is polymorphic (trait objects, dynamic dispatch)
1013    /// - `false` for monomorphic types (default)
1014    ///
1015    /// # Examples of Polymorphic Types
1016    ///
1017    /// - Trait objects: `Box<dyn Trait>`, `Rc<dyn Trait>`, `Arc<dyn Trait>`
1018    ///
1019    /// # Implementation Notes
1020    ///
1021    /// - Implemented by Fory for all polymorphic types
1022    /// - User types with custom serialization typically should not override this
1023    /// - Used to determine if type info must be written
1024    #[inline(always)]
1025    fn fory_is_polymorphic() -> bool
1026    where
1027        Self: Sized,
1028    {
1029        false
1030    }
1031
1032    /// Check if this type is a shared reference (Rc/Arc).
1033    ///
1034    /// Shared references require special handling for reference tracking
1035    /// to support proper sharing and circular reference detection.
1036    ///
1037    /// # Returns
1038    ///
1039    /// - `true` if the type is `Rc<T>` or `Arc<T>`
1040    /// - `false` for all other types (default)
1041    ///
1042    /// # Implementation Notes
1043    ///
1044    /// - Implemented by Fory for `Rc<T>` and `Arc<T>`
1045    /// - User types with custom serialization should not override this
1046    /// - Used for reference tracking and deduplication
1047    #[inline(always)]
1048    fn fory_is_shared_ref() -> bool
1049    where
1050        Self: Sized,
1051    {
1052        false
1053    }
1054
1055    #[inline(always)]
1056    fn fory_is_wrapper_type() -> bool
1057    where
1058        Self: Sized,
1059    {
1060        Self::fory_is_shared_ref()
1061    }
1062
1063    /// Get the static Fory type ID for this type.
1064    ///
1065    /// Type IDs are Fory's internal type identification system, separate from
1066    /// Rust's `std::any::TypeId`. They're used for cross-language serialization
1067    /// and protocol compatibility.
1068    ///
1069    /// # Returns
1070    ///
1071    /// - For built-in types: Specific type ID (e.g., `TypeId::I32`, `TypeId::STRING`)
1072    /// - For external types: `TypeId::EXT` (default)
1073    ///
1074    /// # Type ID Categories
1075    ///
1076    /// - **Primitives**: `BOOL`, `I8`, `I16`, `I32`, `I64`, `U8`, `U16`, `U32`, `U64`, `USIZE`, `U128`, `F32`, `F64`
1077    /// - **Strings**: `STRING`
1078    /// - **Collections**: `LIST`, `MAP`, `SET`
1079    /// - **Structs**: `STRUCT`
1080    /// - **Enums**: `ENUM`
1081    /// - **User types**: `EXT` for user types with custom serialization logic
1082    ///
1083    /// # Implementation Notes
1084    ///
1085    /// - Default returns `TypeId::EXT` for user types
1086    /// - Fory implements specific type IDs for all built-in types
1087    /// - User types with custom serialization should use the default
1088    /// - This is a compile-time constant
1089    #[inline(always)]
1090    fn fory_static_type_id() -> TypeId
1091    where
1092        Self: Sized,
1093    {
1094        // set to ext to simplify the user defined serializer.
1095        // serializer for other types will override this method.
1096        TypeId::EXT
1097    }
1098
1099    /// Get the registered type ID from the type resolver.
1100    ///
1101    /// This method looks up the type's assigned ID in the type registry,
1102    /// which is required for serialization of external types.
1103    ///
1104    /// # Parameters
1105    ///
1106    /// * `type_resolver` - The type registry to query
1107    ///
1108    /// # Returns
1109    ///
1110    /// The numeric type ID assigned to this type during registration.
1111    ///
1112    /// # Errors
1113    ///
1114    /// Returns an error if the type is not registered with the resolver.
1115    ///
1116    /// # Implementation Notes
1117    ///
1118    /// - Default implementation looks up via `std::any::TypeId`
1119    /// - User types must be registered before serialization
1120    /// - Built-in types have pre-assigned IDs
1121    /// - This is typically called by [`fory_type_id_dyn`]
1122    ///
1123    /// [`fory_type_id_dyn`]: Serializer::fory_type_id_dyn
1124    #[inline(always)]
1125    fn fory_get_type_id(type_resolver: &TypeResolver) -> Result<u32, Error>
1126    where
1127        Self: Sized,
1128    {
1129        match type_resolver.get_type_info(&std::any::TypeId::of::<Self>()) {
1130            Ok(info) => Ok(info.get_type_id()),
1131            Err(e) => Err(Error::enhance_type_error::<Self>(e)),
1132        }
1133    }
1134
1135    /// **[USER IMPLEMENTATION REQUIRED]** Get the runtime type ID for this instance.
1136    ///
1137    /// This method returns the type ID for the actual runtime type of the instance,
1138    /// which may differ from the static type for polymorphic types.
1139    ///
1140    /// # Parameters
1141    ///
1142    /// * `type_resolver` - The type registry to query
1143    ///
1144    /// # Returns
1145    ///
1146    /// The numeric type ID for this instance's runtime type.
1147    ///
1148    /// # Implementation Pattern
1149    ///
1150    /// For most types, simply delegate to [`fory_get_type_id`]:
1151    ///
1152    /// ```rust,ignore
1153    /// fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<u32, Error> {
1154    ///     Self::fory_get_type_id(type_resolver)
1155    /// }
1156    /// ```
1157    ///
1158    /// For polymorphic types, return the actual runtime type:
1159    ///
1160    /// ```rust,ignore
1161    /// fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<u32, Error> {
1162    ///     // Get the actual type ID based on runtime type
1163    ///     self.get_actual_type().fory_get_type_id(type_resolver)
1164    /// }
1165    /// ```
1166    ///
1167    /// [`fory_get_type_id`]: Serializer::fory_get_type_id
1168    fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<u32, Error>;
1169
1170    /// Get Rust's `std::any::TypeId` for this instance.
1171    ///
1172    /// Returns the runtime type identifier from Rust's type system.
1173    /// This is used for type resolution and registration.
1174    ///
1175    /// # Returns
1176    ///
1177    /// The `std::any::TypeId` for this instance's concrete type.
1178    ///
1179    /// # Implementation Notes
1180    ///
1181    /// - Default implementation uses `TypeId::of::<Self>()`
1182    /// - User types with custom serialization should not override this
1183    /// - Used by type resolution infrastructure
1184    #[inline(always)]
1185    fn fory_concrete_type_id(&self) -> std::any::TypeId {
1186        std::any::TypeId::of::<Self>()
1187    }
1188
1189    /// Hint for buffer pre-allocation size.
1190    ///
1191    /// This method provides a size hint for how much buffer space to pre-allocate
1192    /// before serializing this type. Accurate hints improve performance by reducing
1193    /// buffer reallocations.
1194    ///
1195    /// # Returns
1196    ///
1197    /// - Estimated maximum size in bytes for this type
1198    /// - `0` if unknown or variable size (default)
1199    ///
1200    /// # Implementation Guidelines
1201    ///
1202    /// Return a conservative upper bound:
1203    ///
1204    /// ```rust,ignore
1205    /// fn fory_reserved_space() -> usize {
1206    ///     std::mem::size_of::<Self>() + overhead
1207    /// }
1208    /// ```
1209    ///
1210    /// # Examples
1211    ///
1212    /// - Fixed-size struct: `std::mem::size_of::<Self>() + metadata_size`
1213    /// - Variable-size: Return `0` (collections, strings)
1214    ///
1215    /// # Implementation Notes
1216    ///
1217    /// - Default returns `0` (no pre-allocation)
1218    /// - Fory implements size hints for fixed-size types
1219    /// - User types with custom serialization can override for performance
1220    /// - Overestimation wastes memory; underestimation requires reallocation
1221    #[inline(always)]
1222    fn fory_reserved_space() -> usize
1223    where
1224        Self: Sized,
1225    {
1226        std::mem::size_of::<Self>()
1227    }
1228
1229    /// **[USER IMPLEMENTATION REQUIRED]** Downcast to `&dyn Any` for dynamic type checking.
1230    ///
1231    /// This method enables runtime type checking and downcasting, required for
1232    /// Fory's type system integration.
1233    ///
1234    /// # Returns
1235    ///
1236    /// A reference to this instance as `&dyn Any`.
1237    ///
1238    /// # Implementation Pattern
1239    ///
1240    /// Always implement this by returning `self`:
1241    ///
1242    /// ```rust,ignore
1243    /// fn as_any(&self) -> &dyn Any {
1244    ///     self
1245    /// }
1246    /// ```
1247    ///
1248    /// # Implementation Notes
1249    ///
1250    /// - Required for all types implementing `Serializer`
1251    /// - Enables `downcast_ref::<T>()` on serialized values
1252    /// - Used by Fory's polymorphic deserialization
1253    fn as_any(&self) -> &dyn Any;
1254}
1255
1256/// Extended trait for struct and enum serialization.
1257///
1258/// `StructSerializer` extends [`Serializer`] with capabilities specific to struct and enum types,
1259/// including field metadata, schema evolution, and compatibility features. This trait is used
1260/// internally by Fory and automatically implemented by the derive macro.
1261///
1262/// # ⚠️ Important: Do NOT Implement This for Custom User Types
1263///
1264/// **User types with custom serialization should NOT implement this trait.** This trait is:
1265///
1266/// - **Only for derive-based types**: Automatically implemented by `#[derive(ForyObject)]`
1267/// - **Internal infrastructure**: Used by Fory's struct/enum deserialization engine
1268/// - **Not for manual implementation**: Unless you're extending Fory's core functionality
1269///
1270/// For user types that need custom serialization logic (EXT types), implement only the [`Serializer`] trait.
1271///
1272/// # Purpose
1273///
1274/// This trait enables Fory's advanced struct/enum features:
1275///
1276/// - **Field introspection**: Access to struct field metadata for serialization
1277/// - **Schema evolution**: Forward and backward compatibility for struct/enum changes
1278/// - **Compatible deserialization**: Read structs with different field sets (added/removed fields)
1279/// - **Type indexing**: Efficient type lookup for struct/enum types
1280/// - **Hash-based identification**: Support for versioned struct schemas
1281///
1282/// # Automatic Implementation
1283///
1284/// The `#[derive(ForyObject)]` macro automatically implements this trait for structs and enums:
1285///
1286/// ```rust,ignore
1287/// #[derive(ForyObject)]
1288/// struct Point {
1289///     x: f64,
1290///     y: f64,
1291/// }
1292/// // StructSerializer is automatically implemented
1293/// // Users should never implement this manually for custom serialization
1294/// ```
1295///
1296/// # Usage by Fory
1297///
1298/// Fory uses this trait internally for:
1299///
1300/// - **Struct serialization**: Writing field metadata and data
1301/// - **Enum serialization**: Writing variant information
1302/// - **Compatible reads**: Handling schema evolution scenarios
1303/// - **Type registration**: Managing struct/enum type metadata
1304///
1305/// # Implementation Notes
1306///
1307/// - **Do not implement manually** for user types with custom serialization (EXT types)
1308/// - **Only via derive macro**: `#[derive(ForyObject)]` is the only supported way
1309/// - **Internal use only**: Methods are called by Fory's serialization engine
1310/// - **Schema evolution**: Enables adding/removing fields without breaking compatibility
1311///
1312/// # See Also
1313///
1314/// - [`Serializer`]: Base trait that user types with custom serialization should implement
1315/// - [`FieldInfo`]: Metadata about struct fields
1316///
1317/// [`Serializer`]: Serializer
1318pub trait StructSerializer: Serializer + 'static {
1319    /// Get metadata about this struct's fields.
1320    ///
1321    /// Returns information about each field in the struct, including names,
1322    /// types, and offsets. This is used for schema evolution and compatibility.
1323    ///
1324    /// # Parameters
1325    ///
1326    /// * `type_resolver` - The type registry for looking up field types
1327    ///
1328    /// # Returns
1329    ///
1330    /// A vector of [`FieldInfo`] describing each field, or an empty vector by default.
1331    ///
1332    /// # Implementation Notes
1333    ///
1334    /// - Implemented automatically by `#[derive(ForyObject)]` macro
1335    /// - Default returns empty vector (no fields)
1336    /// - **Do not implement** for user types with custom serialization (EXT types)
1337    #[allow(unused_variables)]
1338    fn fory_fields_info(type_resolver: &TypeResolver) -> Result<Vec<FieldInfo>, Error> {
1339        Ok(Vec::default())
1340    }
1341
1342    #[allow(unused_variables)]
1343    fn fory_variants_fields_info(
1344        type_resolver: &TypeResolver,
1345    ) -> Result<Vec<(String, std::any::TypeId, Vec<FieldInfo>)>, Error> {
1346        Ok(Vec::default())
1347    }
1348
1349    /// Get the type index for fast struct type lookup.
1350    ///
1351    /// Type index provides O(1) lookup for struct types in the type registry.
1352    ///
1353    /// # Returns
1354    ///
1355    /// A unique index assigned to this struct type.
1356    ///
1357    /// # Implementation Notes
1358    ///
1359    /// - Implemented automatically by `#[derive(ForyObject)]` macro
1360    /// - Used for efficient type resolution
1361    /// - **Do not implement** for user types with custom serialization (EXT types)
1362    fn fory_type_index() -> u32 {
1363        unimplemented!()
1364    }
1365
1366    /// Get the actual type ID considering registration and compatibility modes.
1367    ///
1368    /// This method computes the effective type ID based on how the type was registered
1369    /// and whether compatibility mode is enabled.
1370    ///
1371    /// # Parameters
1372    ///
1373    /// * `type_id` - The base type ID
1374    /// * `register_by_name` - Whether type was registered by name (vs by hash)
1375    /// * `compatible` - Whether compatibility mode is enabled
1376    ///
1377    /// # Returns
1378    ///
1379    /// The actual type ID to use for serialization/deserialization.
1380    ///
1381    /// # Implementation Notes
1382    ///
1383    /// - Default delegates to `struct_::actual_type_id`
1384    /// - Handles type ID transformations for compatibility
1385    /// - **Do not override** for user types with custom serialization (EXT types)
1386    #[inline(always)]
1387    fn fory_actual_type_id(type_id: u32, register_by_name: bool, compatible: bool) -> u32 {
1388        struct_::actual_type_id(type_id, register_by_name, compatible)
1389    }
1390
1391    /// Get sorted field names for consistent serialization order.
1392    ///
1393    /// Returns field names in sorted order to ensure deterministic serialization
1394    /// and enable schema evolution.
1395    ///
1396    /// # Returns
1397    ///
1398    /// A static slice of field names in sorted order, or empty slice by default.
1399    ///
1400    /// # Implementation Notes
1401    ///
1402    /// - Implemented automatically by `#[derive(ForyObject)]` macro
1403    /// - Used for field ordering and compatibility
1404    /// - Field order affects wire format
1405    /// - **Do not implement** for user types with custom serialization (EXT types)
1406    fn fory_get_sorted_field_names() -> &'static [&'static str] {
1407        &[]
1408    }
1409
1410    /// Deserialize a struct with schema compatibility support.
1411    ///
1412    /// This method enables reading structs even when the reader's schema differs
1413    /// from the writer's schema. It handles:
1414    ///
1415    /// - Missing fields (uses defaults)
1416    /// - Extra fields (skips them)
1417    /// - Reordered fields
1418    /// - Type changes (within compatibility rules)
1419    ///
1420    /// # Parameters
1421    ///
1422    /// * `context` - Read context with buffer and resolvers
1423    /// * `type_info` - Type metadata from the serialized data
1424    ///
1425    /// # Returns
1426    ///
1427    /// A deserialized instance with compatible field mapping.
1428    ///
1429    /// # Errors
1430    ///
1431    /// Returns an error if:
1432    ///
1433    /// - Required fields are missing without defaults
1434    /// - Field types are incompatible
1435    /// - Data is corrupted
1436    ///
1437    /// # Implementation Notes
1438    ///
1439    /// - Implemented automatically by `#[derive(ForyObject)]` macro
1440    /// - Enables forward and backward compatibility
1441    /// - Uses field names for matching when possible
1442    /// - Falls back to field order for unnamed fields
1443    /// - **Do not implement** for user types with custom serialization (EXT types)
1444    fn fory_read_compatible(
1445        context: &mut ReadContext,
1446        type_info: Rc<TypeInfo>,
1447    ) -> Result<Self, Error>
1448    where
1449        Self: Sized;
1450}
1451
1452/// Serializes an object implementing `Serializer` to the write context.
1453///
1454/// This is a convenience wrapper around `T::fory_write_data` that delegates to the type's
1455/// serialization implementation.
1456#[inline(always)]
1457pub fn write_data<T: Serializer>(this: &T, context: &mut WriteContext) -> Result<(), Error> {
1458    T::fory_write_data(this, context)
1459}
1460
1461/// Deserializes an object implementing `Serializer` from the read context.
1462///
1463/// This is a convenience wrapper around `T::fory_read_data` that delegates to the type's
1464/// deserialization implementation. Requires `ForyDefault` for instance creation.
1465#[inline(always)]
1466pub fn read_data<T: Serializer + ForyDefault>(context: &mut ReadContext) -> Result<T, Error> {
1467    T::fory_read_data(context)
1468}