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