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    /// Deserialize data for dynamic send-sync carriers.
894    ///
895    /// This method must construct the `Box<dyn Any + Send + Sync>` from the
896    /// concrete value before it is erased as `dyn Any`. It must never try to
897    /// upgrade a `Box<dyn Any>` returned by the ordinary dynamic read path.
898    #[inline(always)]
899    fn fory_read_data_as_send_sync_any(
900        context: &mut ReadContext,
901    ) -> Result<Box<dyn Any + Send + Sync>, Error>
902    where
903        Self: Sized + ForyDefault,
904    {
905        let _ = context;
906        Err(crate::error::unsupported_send_sync_type::<Self>())
907    }
908
909    /// Read and validate type metadata from the buffer.
910    ///
911    /// This method reads type information to verify that the data in the buffer
912    /// matches the expected type. It's the counterpart to [`fory_write_type_info`].
913    ///
914    /// # Default Implementation
915    ///
916    /// The default implementation reads and validates the type info:
917    ///
918    /// ```rust,ignore
919    /// fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
920    ///     context.read_any_type_info()?;
921    ///     Ok(())
922    /// }
923    /// ```
924    ///
925    /// # When to Override
926    ///
927    /// Override this method for:
928    ///
929    /// - **Built-in types**: Fory's internal types override for optimized performance
930    /// - **Custom validation logic**: If you need special type checking
931    ///
932    /// For user types with custom serialization, the default implementation is typically sufficient.
933    ///
934    /// # Implementation Notes
935    ///
936    /// - Called by [`fory_read`] when `read_type_info` is true
937    /// - Implemented by Fory for all built-in types with optimized paths
938    /// - User types with custom serialization rarely need to override this
939    ///
940    /// [`fory_write_type_info`]: Serializer::fory_write_type_info
941    /// [`fory_read`]: Serializer::fory_read
942    #[inline(always)]
943    fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error>
944    where
945        Self: Sized,
946    {
947        // Serializer for internal types should overwrite this method for faster performance.
948        context.read_any_type_info()?;
949        Ok(())
950    }
951
952    /// Check if this type is `Option<T>`.
953    ///
954    /// # Returns
955    ///
956    /// - `true` if the type is `Option<T>`
957    /// - `false` for all other types (default)
958    ///
959    /// # Implementation Notes
960    ///
961    /// - Implemented by Fory for `Option<T>` to return `true`
962    /// - User types with custom serialization should not override this
963    /// - Used internally for null handling optimization
964    #[inline(always)]
965    fn fory_is_option() -> bool
966    where
967        Self: Sized,
968    {
969        false
970    }
971
972    /// Check if this instance represents a `None` value.
973    ///
974    /// This method is used for runtime checking of optional values.
975    ///
976    /// # Returns
977    ///
978    /// - `true` if the instance is `Option::None`
979    /// - `false` for all other values (default)
980    ///
981    /// # Implementation Notes
982    ///
983    /// - Implemented by Fory for `Option<T>` to check None state
984    /// - User types with custom serialization should not override this
985    /// - Used with [`fory_is_option`] for null handling
986    ///
987    /// [`fory_is_option`]: Serializer::fory_is_option
988    #[inline(always)]
989    fn fory_is_none(&self) -> bool {
990        false
991    }
992
993    /// Check if this type supports polymorphic serialization.
994    ///
995    /// Polymorphic types can have different runtime types than their static type,
996    /// requiring special handling during serialization and deserialization.
997    ///
998    /// # Returns
999    ///
1000    /// - `true` if the type is polymorphic (trait objects, dynamic dispatch)
1001    /// - `false` for monomorphic types (default)
1002    ///
1003    /// # Examples of Polymorphic Types
1004    ///
1005    /// - Trait objects: `Box<dyn Trait>`, `Rc<dyn Trait>`, `Arc<dyn Trait>`
1006    ///
1007    /// # Implementation Notes
1008    ///
1009    /// - Implemented by Fory for all polymorphic types
1010    /// - User types with custom serialization typically should not override this
1011    /// - Used to determine if type info must be written
1012    #[inline(always)]
1013    fn fory_is_polymorphic() -> bool
1014    where
1015        Self: Sized,
1016    {
1017        false
1018    }
1019
1020    /// Check if this type is a shared reference (Rc/Arc).
1021    ///
1022    /// Shared references require special handling for reference tracking
1023    /// to support proper sharing and circular reference detection.
1024    ///
1025    /// # Returns
1026    ///
1027    /// - `true` if the type is `Rc<T>` or `Arc<T>`
1028    /// - `false` for all other types (default)
1029    ///
1030    /// # Implementation Notes
1031    ///
1032    /// - Implemented by Fory for `Rc<T>` and `Arc<T>`
1033    /// - User types with custom serialization should not override this
1034    /// - Used for reference tracking and deduplication
1035    #[inline(always)]
1036    fn fory_is_shared_ref() -> bool
1037    where
1038        Self: Sized,
1039    {
1040        false
1041    }
1042
1043    #[inline(always)]
1044    fn fory_is_wrapper_type() -> bool
1045    where
1046        Self: Sized,
1047    {
1048        Self::fory_is_shared_ref()
1049    }
1050
1051    /// Get the static Fory type ID for this type.
1052    ///
1053    /// Type IDs are Fory's internal type identification system, separate from
1054    /// Rust's `std::any::TypeId`. They're used for cross-language serialization
1055    /// and protocol compatibility.
1056    ///
1057    /// # Returns
1058    ///
1059    /// - For built-in types: Specific type ID (e.g., `TypeId::I32`, `TypeId::STRING`)
1060    /// - For external types: `TypeId::EXT` (default)
1061    ///
1062    /// # Type ID Categories
1063    ///
1064    /// - **Primitives**: `BOOL`, `I8`, `I16`, `I32`, `I64`, `U8`, `U16`, `U32`, `U64`, `USIZE`, `U128`, `F32`, `F64`
1065    /// - **Strings**: `STRING`
1066    /// - **Collections**: `LIST`, `MAP`, `SET`
1067    /// - **Structs**: `STRUCT`
1068    /// - **Enums**: `ENUM`
1069    /// - **User types**: `EXT` for user types with custom serialization logic
1070    ///
1071    /// # Implementation Notes
1072    ///
1073    /// - Default returns `TypeId::EXT` for user types
1074    /// - Fory implements specific type IDs for all built-in types
1075    /// - User types with custom serialization should use the default
1076    /// - This is a compile-time constant
1077    #[inline(always)]
1078    fn fory_static_type_id() -> TypeId
1079    where
1080        Self: Sized,
1081    {
1082        // set to ext to simplify the user defined serializer.
1083        // serializer for other types will override this method.
1084        TypeId::EXT
1085    }
1086
1087    /// Get the registered type ID from the type resolver.
1088    ///
1089    /// This method looks up the type's assigned ID in the type registry,
1090    /// which is required for serialization of external types.
1091    ///
1092    /// # Parameters
1093    ///
1094    /// * `type_resolver` - The type registry to query
1095    ///
1096    /// # Returns
1097    ///
1098    /// The numeric type ID assigned to this type during registration.
1099    ///
1100    /// # Errors
1101    ///
1102    /// Returns an error if the type is not registered with the resolver.
1103    ///
1104    /// # Implementation Notes
1105    ///
1106    /// - Default implementation looks up via `std::any::TypeId`
1107    /// - User types must be registered before serialization
1108    /// - Built-in types have pre-assigned IDs
1109    /// - This is typically called by [`fory_type_id_dyn`]
1110    ///
1111    /// [`fory_type_id_dyn`]: Serializer::fory_type_id_dyn
1112    #[inline(always)]
1113    fn fory_get_type_id(type_resolver: &TypeResolver) -> Result<TypeId, Error>
1114    where
1115        Self: Sized,
1116    {
1117        match type_resolver.get_type_info(&std::any::TypeId::of::<Self>()) {
1118            Ok(info) => Ok(info.get_type_id()),
1119            Err(e) => Err(Error::enhance_type_error::<Self>(e)),
1120        }
1121    }
1122
1123    #[inline(always)]
1124    fn fory_get_type_info(type_resolver: &TypeResolver) -> Result<Rc<TypeInfo>, Error>
1125    where
1126        Self: Sized,
1127    {
1128        match type_resolver.get_type_info(&std::any::TypeId::of::<Self>()) {
1129            Ok(info) => Ok(info),
1130            Err(e) => Err(Error::enhance_type_error::<Self>(e)),
1131        }
1132    }
1133
1134    /// **[USER IMPLEMENTATION REQUIRED]** Get the runtime type ID for this instance.
1135    ///
1136    /// This method returns the type ID for the actual runtime type of the instance,
1137    /// which may differ from the static type for polymorphic types.
1138    ///
1139    /// # Parameters
1140    ///
1141    /// * `type_resolver` - The type registry to query
1142    ///
1143    /// # Returns
1144    ///
1145    /// The numeric type ID for this instance's runtime type.
1146    ///
1147    /// # Implementation Pattern
1148    ///
1149    /// For most types, simply delegate to [`fory_get_type_id`]:
1150    ///
1151    /// ```rust,ignore
1152    /// fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<fory_core::TypeId, Error> {
1153    ///     Self::fory_get_type_id(type_resolver)
1154    /// }
1155    /// ```
1156    ///
1157    /// For polymorphic types, return the actual runtime type:
1158    ///
1159    /// ```rust,ignore
1160    /// fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<fory_core::TypeId, Error> {
1161    ///     // Get the actual type ID based on runtime type
1162    ///     self.get_actual_type().fory_get_type_id(type_resolver)
1163    /// }
1164    /// ```
1165    ///
1166    /// [`fory_get_type_id`]: Serializer::fory_get_type_id
1167    fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<TypeId, Error>;
1168
1169    /// Get Rust's `std::any::TypeId` for this instance.
1170    ///
1171    /// Returns the runtime type identifier from Rust's type system.
1172    /// This is used for type resolution and registration.
1173    ///
1174    /// # Returns
1175    ///
1176    /// The `std::any::TypeId` for this instance's concrete type.
1177    ///
1178    /// # Implementation Notes
1179    ///
1180    /// - Default implementation uses `TypeId::of::<Self>()`
1181    /// - User types with custom serialization should not override this
1182    /// - Used by type resolution infrastructure
1183    #[inline(always)]
1184    fn fory_concrete_type_id(&self) -> std::any::TypeId {
1185        std::any::TypeId::of::<Self>()
1186    }
1187
1188    /// Hint for buffer pre-allocation size.
1189    ///
1190    /// This method provides a size hint for how much buffer space to pre-allocate
1191    /// before serializing this type. Accurate hints improve performance by reducing
1192    /// buffer reallocations.
1193    ///
1194    /// # Returns
1195    ///
1196    /// - Estimated maximum size in bytes for this type
1197    /// - `0` if unknown or variable size (default)
1198    ///
1199    /// # Implementation Guidelines
1200    ///
1201    /// Return a conservative upper bound:
1202    ///
1203    /// ```rust,ignore
1204    /// fn fory_reserved_space() -> usize {
1205    ///     std::mem::size_of::<Self>() + overhead
1206    /// }
1207    /// ```
1208    ///
1209    /// # Examples
1210    ///
1211    /// - Fixed-size struct: `std::mem::size_of::<Self>() + metadata_size`
1212    /// - Variable-size: Return `0` (collections, strings)
1213    ///
1214    /// # Implementation Notes
1215    ///
1216    /// - Default returns `0` (no pre-allocation)
1217    /// - Fory implements size hints for fixed-size types
1218    /// - User types with custom serialization can override for performance
1219    /// - Overestimation wastes memory; underestimation requires reallocation
1220    #[inline(always)]
1221    fn fory_reserved_space() -> usize
1222    where
1223        Self: Sized,
1224    {
1225        std::mem::size_of::<Self>()
1226    }
1227
1228    /// **[USER IMPLEMENTATION REQUIRED]** Downcast to `&dyn Any` for dynamic type checking.
1229    ///
1230    /// This method enables runtime type checking and downcasting, required for
1231    /// Fory's type system integration.
1232    ///
1233    /// # Returns
1234    ///
1235    /// A reference to this instance as `&dyn Any`.
1236    ///
1237    /// # Implementation Pattern
1238    ///
1239    /// Always implement this by returning `self`:
1240    ///
1241    /// ```rust,ignore
1242    /// fn as_any(&self) -> &dyn Any {
1243    ///     self
1244    /// }
1245    /// ```
1246    ///
1247    /// # Implementation Notes
1248    ///
1249    /// - Required for all types implementing `Serializer`
1250    /// - Enables `downcast_ref::<T>()` on serialized values
1251    /// - Used by Fory's polymorphic deserialization
1252    fn as_any(&self) -> &dyn Any;
1253}
1254
1255/// Extended trait for struct and enum serialization.
1256///
1257/// `StructSerializer` extends [`Serializer`] with capabilities specific to struct and enum types,
1258/// including field metadata, schema evolution, and compatibility features. This trait is used
1259/// internally by Fory and automatically implemented by the derive macro.
1260///
1261/// # Important: Do NOT Implement This for Custom User Types
1262///
1263/// **User types with custom serialization should NOT implement this trait.** This trait is:
1264///
1265/// - **Only for derive-based types**: Automatically implemented by `#[derive(ForyStruct)]`
1266/// - **Internal infrastructure**: Used by Fory's struct/enum deserialization engine
1267/// - **Not for manual implementation**: Unless you're extending Fory's core functionality
1268///
1269/// For user types that need custom serialization logic (EXT types), implement only the [`Serializer`] trait.
1270///
1271/// # Purpose
1272///
1273/// This trait enables Fory's advanced struct/enum features:
1274///
1275/// - **Field introspection**: Access to struct field metadata for serialization
1276/// - **Schema evolution**: Forward and backward compatibility for struct/enum changes
1277/// - **Compatible deserialization**: Read structs with different field sets (added/removed fields)
1278/// - **Type indexing**: Efficient type lookup for struct/enum types
1279/// - **Hash-based identification**: Support for versioned struct schemas
1280///
1281/// # Automatic Implementation
1282///
1283/// The `#[derive(ForyStruct)]` macro automatically implements this trait for structs and enums:
1284///
1285/// ```rust,ignore
1286/// #[derive(ForyStruct)]
1287/// struct Point {
1288///     x: f64,
1289///     y: f64,
1290/// }
1291/// // StructSerializer is automatically implemented
1292/// // Users should never implement this manually for custom serialization
1293/// ```
1294///
1295/// # Usage by Fory
1296///
1297/// Fory uses this trait internally for:
1298///
1299/// - **Struct serialization**: Writing field metadata and data
1300/// - **Enum serialization**: Writing variant information
1301/// - **Compatible reads**: Handling schema evolution scenarios
1302/// - **Type registration**: Managing struct/enum type metadata
1303///
1304/// # Implementation Notes
1305///
1306/// - **Do not implement manually** for user types with custom serialization (EXT types)
1307/// - **Only via derive macro**: `#[derive(ForyStruct)]` is the only supported way
1308/// - **Internal use only**: Methods are called by Fory's serialization engine
1309/// - **Schema evolution**: Enables adding/removing fields without breaking compatibility
1310///
1311/// # See Also
1312///
1313/// - [`Serializer`]: Base trait that user types with custom serialization should implement
1314/// - [`FieldInfo`]: Metadata about struct fields
1315///
1316/// [`Serializer`]: Serializer
1317pub trait StructSerializer: Serializer + 'static {
1318    /// Get metadata about this struct's fields.
1319    ///
1320    /// Returns information about each field in the struct, including names,
1321    /// types, and offsets. This is used for schema evolution and compatibility.
1322    ///
1323    /// # Parameters
1324    ///
1325    /// * `type_resolver` - The type registry for looking up field types
1326    ///
1327    /// # Returns
1328    ///
1329    /// A vector of [`FieldInfo`] describing each field, or an empty vector by default.
1330    ///
1331    /// # Implementation Notes
1332    ///
1333    /// - Implemented automatically by `#[derive(ForyStruct)]` macro
1334    /// - Default returns empty vector (no fields)
1335    /// - **Do not implement** for user types with custom serialization (EXT types)
1336    #[allow(unused_variables)]
1337    fn fory_fields_info(type_resolver: &TypeResolver) -> Result<Vec<FieldInfo>, Error> {
1338        Ok(Vec::default())
1339    }
1340
1341    #[allow(unused_variables)]
1342    fn fory_variants_fields_info(
1343        type_resolver: &TypeResolver,
1344    ) -> Result<Vec<(String, std::any::TypeId, Vec<FieldInfo>)>, Error> {
1345        Ok(Vec::default())
1346    }
1347
1348    /// Get the type index for fast struct type lookup.
1349    ///
1350    /// Type index provides O(1) lookup for struct types in the type registry.
1351    ///
1352    /// # Returns
1353    ///
1354    /// A unique index assigned to this struct type.
1355    ///
1356    /// # Implementation Notes
1357    ///
1358    /// - Implemented automatically by `#[derive(ForyStruct)]` macro
1359    /// - Used for efficient type resolution
1360    /// - **Do not implement** for user types with custom serialization (EXT types)
1361    fn fory_type_index() -> u32 {
1362        unimplemented!()
1363    }
1364
1365    /// Get the actual type ID considering registration and compatibility modes.
1366    ///
1367    /// This method computes the effective type ID based on how the type was registered
1368    /// and whether compatibility mode is enabled.
1369    ///
1370    /// # Parameters
1371    ///
1372    /// * `type_id` - The base type ID
1373    /// * `register_by_name` - Whether type was registered by name (vs by hash)
1374    /// * `compatible` - Whether compatibility mode is enabled
1375    /// * `xlang` - Whether xlang mode is enabled
1376    ///
1377    /// # Returns
1378    ///
1379    /// The actual type ID to use for serialization/deserialization.
1380    ///
1381    /// # Implementation Notes
1382    ///
1383    /// - Default delegates to `struct_::actual_type_id`
1384    /// - Handles type ID transformations for compatibility
1385    /// - **Do not override** for user types with custom serialization (EXT types)
1386    #[inline(always)]
1387    fn fory_actual_type_id(
1388        type_id: u32,
1389        register_by_name: bool,
1390        compatible: bool,
1391        xlang: bool,
1392    ) -> u32 {
1393        let _ = xlang; // Default implementation ignores xlang parameter
1394        struct_::actual_type_id(type_id, register_by_name, compatible)
1395    }
1396
1397    /// Get sorted field names for consistent serialization order.
1398    ///
1399    /// Returns field names in sorted order to ensure deterministic serialization
1400    /// and enable schema evolution.
1401    ///
1402    /// # Returns
1403    ///
1404    /// A static slice of field names in sorted order, or empty slice by default.
1405    ///
1406    /// # Implementation Notes
1407    ///
1408    /// - Implemented automatically by `#[derive(ForyStruct)]` macro
1409    /// - Used for field ordering and compatibility
1410    /// - Field order affects wire format
1411    /// - **Do not implement** for user types with custom serialization (EXT types)
1412    fn fory_get_sorted_field_names() -> &'static [&'static str] {
1413        &[]
1414    }
1415
1416    /// Deserialize a struct with schema compatibility support.
1417    ///
1418    /// This method enables reading structs even when the reader's schema differs
1419    /// from the writer's schema. It handles:
1420    ///
1421    /// - Missing fields (uses defaults)
1422    /// - Extra fields (skips them)
1423    /// - Reordered fields
1424    /// - Type changes (within compatibility rules)
1425    ///
1426    /// # Parameters
1427    ///
1428    /// * `context` - Read context with buffer and resolvers
1429    /// * `type_info` - Type metadata from the serialized data
1430    ///
1431    /// # Returns
1432    ///
1433    /// A deserialized instance with compatible field mapping.
1434    ///
1435    /// # Errors
1436    ///
1437    /// Returns an error if:
1438    ///
1439    /// - Required fields are missing without defaults
1440    /// - Field types are incompatible
1441    /// - Data is corrupted
1442    ///
1443    /// # Implementation Notes
1444    ///
1445    /// - Implemented automatically by `#[derive(ForyStruct)]` macro
1446    /// - Enables forward and backward compatibility
1447    /// - Uses field names for matching when possible
1448    /// - Falls back to field order for unnamed fields
1449    /// - **Do not implement** for user types with custom serialization (EXT types)
1450    fn fory_read_compatible(
1451        context: &mut ReadContext,
1452        type_info: Rc<TypeInfo>,
1453    ) -> Result<Self, Error>
1454    where
1455        Self: Sized;
1456
1457    /// Deserialize compatible data for dynamic send-sync carriers.
1458    ///
1459    /// Implementations are generated only when the resulting struct/enum is
1460    /// known to be `Send + Sync`.
1461    #[inline(always)]
1462    fn fory_read_compatible_as_send_sync_any(
1463        context: &mut ReadContext,
1464        type_info: Rc<TypeInfo>,
1465    ) -> Result<Box<dyn Any + Send + Sync>, Error>
1466    where
1467        Self: Sized,
1468    {
1469        let _ = context;
1470        let _ = type_info;
1471        Err(crate::error::unsupported_send_sync_type::<Self>())
1472    }
1473}
1474
1475/// Serializes an object implementing `Serializer` to the write context.
1476///
1477/// This is a convenience wrapper around `T::fory_write_data` that delegates to the type's
1478/// serialization implementation.
1479#[inline(always)]
1480pub fn write_data<T: Serializer>(this: &T, context: &mut WriteContext) -> Result<(), Error> {
1481    T::fory_write_data(this, context)
1482}
1483
1484/// Deserializes an object implementing `Serializer` from the read context.
1485///
1486/// This is a convenience wrapper around `T::fory_read_data` that delegates to the type's
1487/// deserialization implementation. Requires `ForyDefault` for instance creation.
1488#[inline(always)]
1489pub fn read_data<T: Serializer + ForyDefault>(context: &mut ReadContext) -> Result<T, Error> {
1490    T::fory_read_data(context)
1491}