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