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