pub struct Fory { /* private fields */ }Expand description
The main Fory serialization framework instance.
Fory provides high-performance cross-language serialization and deserialization
capabilities with support for multiple modes, reference tracking, and trait object serialization.
§Features
- Cross-language serialization: Serialize data in Rust and deserialize in other languages
- Multiple modes: Schema-consistent and compatible serialization modes
- Reference tracking: Handles shared and circular references
- Trait object serialization: Supports serializing polymorphic trait objects
- Dynamic depth limiting: Configurable limit for nested dynamic object serialization
§Examples
Basic usage:
use fory::Fory;
use fory::ForyObject;
#[derive(ForyObject)]
struct User {
name: String,
age: u32,
}
let fory = Fory::default();
let user = User { name: "Alice".to_string(), age: 30 };
let bytes = fory.serialize(&user);
let deserialized: User = fory.deserialize(&bytes).unwrap();Custom configuration:
use fory_core::Fory;
let fory = Fory::default()
.compatible(true)
.compress_string(true)
.max_dyn_depth(10);Implementations§
Source§impl Fory
impl Fory
Sourcepub fn compatible(self, compatible: bool) -> Fory
pub fn compatible(self, compatible: bool) -> Fory
Sets the serialization compatible mode for this Fory instance.
§Arguments
compatible- The serialization compatible mode to use. Options are:false: Schema must be consistent between serialization and deserialization. No metadata is shared. This is the fastest mode.- true`: Supports schema evolution and type metadata sharing for better cross-version compatibility.
§Returns
Returns self for method chaining.
§Note
Setting the compatible mode also automatically configures the share_meta flag:
false→share_meta = false- true
→share_meta = true`
§Examples
use fory_core::Fory;
let fory = Fory::default().compatible(true);Sourcepub fn xlang(self, xlang: bool) -> Fory
pub fn xlang(self, xlang: bool) -> Fory
Enables or disables cross-language serialization protocol.
§Arguments
xlang- Iftrue, uses the cross-language serialization format that includes language metadata and magic numbers for compatibility with Fory implementations in other languages (Java, Python, C++, etc.). Iffalse, uses a Rust-only optimized format.
§Returns
Returns self for method chaining.
§Default
The default value is false.
§Examples
use fory_core::Fory;
// For cross-language use (default)
let fory = Fory::default().xlang(true);
// For Rust-only optimization, this mode is faster and more compact since it avoids
// cross-language metadata and type system costs.
let fory = Fory::default().xlang(false);Sourcepub fn compress_string(self, compress_string: bool) -> Fory
pub fn compress_string(self, compress_string: bool) -> Fory
Enables or disables meta string compression.
§Arguments
compress_string- Iftrue, enables meta string compression to reduce serialized payload size by deduplicating and encoding frequently used strings (such as type names and field names). Iffalse, strings are serialized without compression.
§Returns
Returns self for method chaining.
§Default
The default value is false.
§Trade-offs
- Enabled: Smaller payload size, slightly higher CPU overhead
- Disabled: Larger payload size, faster serialization/deserialization
§Examples
use fory_core::Fory;
let fory = Fory::default().compress_string(true);Sourcepub fn check_struct_version(self, check_struct_version: bool) -> Fory
pub fn check_struct_version(self, check_struct_version: bool) -> Fory
Enables or disables class version checking for schema consistency.
§Arguments
check_struct_version- Iftrue, enables class version checking to ensure schema consistency between serialization and deserialization. When enabled, a version hash computed from field types is written/read to detect schema mismatches. Iffalse, no version checking is performed.
§Returns
Returns self for method chaining.
§Default
The default value is false.
§Note
This feature is only effective when compatible mode is false. In compatible mode,
schema evolution is supported and version checking is not needed.
§Examples
use fory_core::Fory;
let fory = Fory::default()
.compatible(false)
.check_struct_version(true);Sourcepub fn max_dyn_depth(self, max_dyn_depth: u32) -> Fory
pub fn max_dyn_depth(self, max_dyn_depth: u32) -> Fory
Sets the maximum depth for nested dynamic object serialization.
§Arguments
max_dyn_depth- The maximum nesting depth allowed for dynamically-typed objects (e.g., trait objects, boxed types). This prevents stack overflow from deeply nested structures in dynamic serialization scenarios.
§Returns
Returns self for method chaining.
§Default
The default value is 5.
§Behavior
When the depth limit is exceeded during deserialization, an error is returned to prevent potential stack overflow or infinite recursion.
§Examples
use fory_core::Fory;
// Allow deeper nesting for complex object graphs
let fory = Fory::default().max_dyn_depth(10);
// Restrict nesting for safer deserialization
let fory = Fory::default().max_dyn_depth(3);Sourcepub fn is_compatible(&self) -> bool
pub fn is_compatible(&self) -> bool
Returns the current serialization mode.
§Returns
true if the serialization mode is compatible, false otherwise`.
Sourcepub fn is_compress_string(&self) -> bool
pub fn is_compress_string(&self) -> bool
Returns whether string compression is enabled.
§Returns
true if meta string compression is enabled, false otherwise.
Returns whether metadata sharing is enabled.
§Returns
true if metadata sharing is enabled (automatically set based on mode), false otherwise.
Sourcepub fn get_max_dyn_depth(&self) -> u32
pub fn get_max_dyn_depth(&self) -> u32
Returns the maximum depth for nested dynamic object serialization.
Sourcepub fn is_check_struct_version(&self) -> bool
pub fn is_check_struct_version(&self) -> bool
Returns whether class version checking is enabled.
§Returns
true if class version checking is enabled, false otherwise.
Sourcepub fn serialize<T>(&self, record: &T) -> Result<Vec<u8>, Error>where
T: Serializer,
pub fn serialize<T>(&self, record: &T) -> Result<Vec<u8>, Error>where
T: Serializer,
Serializes a value of type T into a byte vector.
§Type Parameters
T- The type of the value to serialize. Must implementSerializer.
§Arguments
record- A reference to the value to serialize.
§Returns
A Vec<u8> containing the serialized data.
§Examples
use fory::Fory;
use fory::ForyObject;
#[derive(ForyObject)]
struct Point { x: i32, y: i32 }
let fory = Fory::default();
let point = Point { x: 10, y: 20 };
let bytes = fory.serialize(&point);Sourcepub fn serialize_to<T>(
&self,
buf: &mut Vec<u8>,
record: &T,
) -> Result<usize, Error>where
T: Serializer,
pub fn serialize_to<T>(
&self,
buf: &mut Vec<u8>,
record: &T,
) -> Result<usize, Error>where
T: Serializer,
Serializes a value of type T into the provided byte buffer.
The serialized data is appended to the end of the buffer by default. To write from a specific position, resize the buffer before calling this method.
§Type Parameters
T- The type of the value to serialize. Must implementSerializer.
§Arguments
buf- A mutable reference to the byte buffer to append the serialized data to. The buffer will be resized as needed during serialization.record- A reference to the value to serialize.
§Returns
The number of bytes written to the buffer on success, or an error if serialization fails.
§Notes
- Multiple
serialize_tocalls to the same buffer will append data sequentially.
§Examples
Basic usage - appending to a buffer:
use fory_core::Fory;
use fory_derive::ForyObject;
#[derive(ForyObject)]
struct Point {
x: i32,
y: i32,
}
let fory = Fory::default();
let point = Point { x: 1, y: 2 };
let mut buf = Vec::new();
let bytes_written = fory.serialize_to(&mut buf, &point).unwrap();
assert_eq!(bytes_written, buf.len());Multiple serializations to the same buffer:
use fory_core::Fory;
use fory_derive::ForyObject;
#[derive(ForyObject, PartialEq, Debug)]
struct Point {
x: i32,
y: i32,
}
let fory = Fory::default();
let p1 = Point { x: 1, y: 2 };
let p2 = Point { x: -3, y: 4 };
let mut buf = Vec::new();
// First serialization
let len1 = fory.serialize_to(&mut buf, &p1).unwrap();
let offset1 = buf.len();
// Second serialization - appends to existing data
let len2 = fory.serialize_to(&mut buf, &p2).unwrap();
let offset2 = buf.len();
assert_eq!(offset1, len1);
assert_eq!(offset2, len1 + len2);
// Deserialize both objects
let deserialized1: Point = fory.deserialize(&buf[0..offset1]).unwrap();
let deserialized2: Point = fory.deserialize(&buf[offset1..offset2]).unwrap();
assert_eq!(deserialized1, p1);
assert_eq!(deserialized2, p2);Writing to a specific position using resize:
§Notes on vec.resize()
When calling vec.resize(n, 0), note that if n is smaller than the current length,
the buffer will be truncated (not shrunk in capacity). The capacity remains unchanged,
making subsequent writes efficient for buffer reuse patterns:
use fory_core::Fory;
use fory_derive::ForyObject;
#[derive(ForyObject)]
struct Point {
x: i32,
y: i32,
}
let fory = Fory::default();
let point = Point { x: 1, y: 2 };
let mut buf = Vec::with_capacity(1024);
buf.resize(16, 0); // Set length to 16 to append the write, capacity stays 1024
let initial_capacity = buf.capacity();
fory.serialize_to(&mut buf, &point).unwrap();
// Reset to smaller size to append the write - capacity unchanged
buf.resize(16, 0);
assert_eq!(buf.capacity(), initial_capacity); // Capacity not shrunk
// Reuse buffer efficiently without reallocation
fory.serialize_to(&mut buf, &point).unwrap();
assert_eq!(buf.capacity(), initial_capacity); // Still no reallocationSourcepub fn register<T>(&mut self, id: u32) -> Result<(), Error>
pub fn register<T>(&mut self, id: u32) -> Result<(), Error>
Registers a struct type with a numeric type ID for serialization.
§Type Parameters
T- The struct type to register. Must implementStructSerializer,Serializer, andForyDefault.
§Arguments
id- A unique numeric identifier for the type. This ID is used in the serialized format to identify the type during deserialization.
§Panics
May panic if the type ID conflicts with an already registered type.
§Examples
use fory::Fory;
use fory::ForyObject;
#[derive(ForyObject)]
struct User { name: String, age: u32 }
let mut fory = Fory::default();
fory.register::<User>(100);Sourcepub fn register_by_namespace<T>(
&mut self,
namespace: &str,
type_name: &str,
) -> Result<(), Error>
pub fn register_by_namespace<T>( &mut self, namespace: &str, type_name: &str, ) -> Result<(), Error>
Registers a struct type with a namespace and type name for cross-language serialization.
§Type Parameters
T- The struct type to register. Must implementStructSerializer,Serializer, andForyDefault.
§Arguments
namespace- The namespace or package name for the type (e.g., “com.example.types”). Use an empty string for the default namespace.type_name- The name of the type (e.g., “User”).
§Notes
This registration method is preferred for cross-language serialization as it uses human-readable type identifiers instead of numeric IDs, which improves compatibility across different language implementations.
§Examples
use fory::Fory;
use fory::ForyObject;
#[derive(ForyObject)]
struct User { name: String, age: u32 }
let mut fory = Fory::default();
fory.register_by_namespace::<User>("com.example", "User");Sourcepub fn register_by_name<T>(&mut self, type_name: &str) -> Result<(), Error>
pub fn register_by_name<T>(&mut self, type_name: &str) -> Result<(), Error>
Registers a struct type with a type name (using the default namespace).
§Type Parameters
T- The struct type to register. Must implementStructSerializer,Serializer, andForyDefault.
§Arguments
type_name- The name of the type (e.g., “User”).
§Notes
This is a convenience method that calls register_by_namespace with an empty namespace string.
§Examples
use fory::Fory;
use fory::ForyObject;
#[derive(ForyObject)]
struct User { name: String, age: u32 }
let mut fory = Fory::default();
fory.register_by_name::<User>("User");Sourcepub fn register_serializer<T>(&mut self, id: u32) -> Result<(), Error>where
T: Serializer + ForyDefault,
pub fn register_serializer<T>(&mut self, id: u32) -> Result<(), Error>where
T: Serializer + ForyDefault,
Registers a custom serializer type with a numeric type ID.
§Type Parameters
T- The type to register. Must implementSerializerandForyDefault. Unlikeregister(), this does not requireStructSerializer, making it suitable for non-struct types or types with custom serialization logic.
§Arguments
id- A unique numeric identifier for the type.
§Use Cases
Use this method to register:
- Enum types with custom serialization
- Wrapper types
- Types with hand-written
Serializerimplementations
§Examples
use fory_core::Fory;
let mut fory = Fory::default();
fory.register_serializer::<MyCustomType>(200);Sourcepub fn register_serializer_by_namespace<T>(
&mut self,
namespace: &str,
type_name: &str,
) -> Result<(), Error>where
T: Serializer + ForyDefault,
pub fn register_serializer_by_namespace<T>(
&mut self,
namespace: &str,
type_name: &str,
) -> Result<(), Error>where
T: Serializer + ForyDefault,
Registers a custom serializer type with a namespace and type name.
§Type Parameters
T- The type to register. Must implementSerializerandForyDefault.
§Arguments
namespace- The namespace or package name for the type.type_name- The name of the type.
§Notes
This is the namespace-based equivalent of register_serializer(), preferred for
cross-language serialization scenarios.
Sourcepub fn register_serializer_by_name<T>(
&mut self,
type_name: &str,
) -> Result<(), Error>where
T: Serializer + ForyDefault,
pub fn register_serializer_by_name<T>(
&mut self,
type_name: &str,
) -> Result<(), Error>where
T: Serializer + ForyDefault,
Registers a custom serializer type with a type name (using the default namespace).
§Type Parameters
T- The type to register. Must implementSerializerandForyDefault.
§Arguments
type_name- The name of the type.
§Notes
This is a convenience method that calls register_serializer_by_namespace with an empty namespace.
Sourcepub fn register_generic_trait<T>(&mut self) -> Result<(), Error>where
T: 'static + Serializer + ForyDefault,
pub fn register_generic_trait<T>(&mut self) -> Result<(), Error>where
T: 'static + Serializer + ForyDefault,
Registers a generic trait object type for serialization.
This method should be used to register collection types such as Vec<T>, HashMap<K, V>, etc.
Don’t register concrete struct types with this method. Use register() instead.
Sourcepub fn write_head<T>(&self, is_none: bool, writer: &mut Writer<'_>)where
T: Serializer,
pub fn write_head<T>(&self, is_none: bool, writer: &mut Writer<'_>)where
T: Serializer,
Writes the serialization header to the writer.
Sourcepub fn deserialize<T>(&self, bf: &[u8]) -> Result<T, Error>where
T: Serializer + ForyDefault,
pub fn deserialize<T>(&self, bf: &[u8]) -> Result<T, Error>where
T: Serializer + ForyDefault,
Deserializes data from a byte slice into a value of type T.
§Type Parameters
T- The target type to deserialize into. Must implementSerializerandForyDefault.
§Arguments
bf- The byte slice containing the serialized data.
§Returns
Ok(T)- The deserialized value on success.Err(Error)- An error if deserialization fails (e.g., invalid format, type mismatch).
§Panics
Panics in debug mode if there are unread bytes remaining after successful deserialization, indicating a potential protocol violation.
§Examples
use fory::Fory;
use fory::ForyObject;
#[derive(ForyObject)]
struct Point { x: i32, y: i32 }
let fory = Fory::default();
let point = Point { x: 10, y: 20 };
let bytes = fory.serialize(&point);
let deserialized: Point = fory.deserialize(&bytes).unwrap();Sourcepub fn deserialize_from<T>(&self, reader: &mut Reader<'_>) -> Result<T, Error>where
T: Serializer + ForyDefault,
pub fn deserialize_from<T>(&self, reader: &mut Reader<'_>) -> Result<T, Error>where
T: Serializer + ForyDefault,
Deserializes data from a Reader into a value of type T.
This method is the paired read operation for serialize_to.
It reads serialized data from the current position of the reader and automatically
advances the cursor to the end of the read data, making it suitable for reading
multiple objects sequentially from the same buffer.
§Type Parameters
T- The target type to deserialize into. Must implementSerializerandForyDefault.
§Arguments
reader- A mutable reference to theReadercontaining the serialized data. The reader’s cursor will be advanced to the end of the deserialized data.
§Returns
Ok(T)- The deserialized value on success.Err(Error)- An error if deserialization fails (e.g., invalid format, type mismatch).
§Notes
- The reader’s cursor is automatically updated after each successful read.
- This method is ideal for reading multiple objects from the same buffer sequentially.
- See
serialize_tofor complete usage examples.
§Examples
Basic usage:
use fory_core::{Fory, Reader};
use fory_derive::ForyObject;
#[derive(ForyObject)]
struct Point { x: i32, y: i32 }
let fory = Fory::default();
let point = Point { x: 10, y: 20 };
let mut buf = Vec::new();
fory.serialize_to(&point, &mut buf).unwrap();
let mut reader = Reader::new(&buf);
let deserialized: Point = fory.deserialize_from(&mut reader).unwrap();