Skip to main content

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