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