pub struct Fory { /* private fields */ }Expand description
The main Fory serialization framework instance.
Fory provides high-performance serialization and deserialization with xlang mode,
native mode, reference tracking, and trait object serialization.
§Features
- Xlang mode: Default wire format for cross-language payloads
- Native mode: Rust-only wire format selected with
.xlang(false) - Schema evolution: Compatible mode by default, with a same-schema optimization available
- 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::{ForyEnum, ForyStruct, ForyUnion};
#[derive(ForyStruct)]
struct User {
name: String,
age: u32,
}
let mut fory = Fory::builder().xlang(true).build();
fory.register_by_name::<User>("example.User").unwrap();
let user = User { name: "Alice".to_string(), age: 30 };
let bytes = fory.serialize(&user).unwrap();
let deserialized: User = fory.deserialize(&bytes).unwrap();Custom configuration:
use fory_core::Fory;
let fory = Fory::builder()
.compress_string(true)
.max_dyn_depth(10)
.build();Implementations§
Source§impl Fory
impl Fory
Sourcepub fn builder() -> ForyBuilder
pub fn builder() -> ForyBuilder
Creates a builder for configuring a Fory instance.
Sourcepub fn is_compatible(&self) -> bool
pub fn is_compatible(&self) -> bool
Returns whether compatible schema evolution is enabled.
§Returns
true if compatible schema evolution is enabled, 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.
Sourcepub fn is_check_string_read(&self) -> bool
pub fn is_check_string_read(&self) -> bool
Returns whether UTF-8 string payload validation is enabled.
Returns whether metadata sharing is enabled.
§Returns
true if metadata sharing is enabled, 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<Target = T>,
pub fn serialize<T>(&self, record: &T) -> Result<Vec<u8>, Error>where
T: Serializer<Target = T>,
Serializes a value of type T into a byte vector.
This is for ordinary roots whose value type selects its own serializer
through T: Serializer<Target = T>. For an external target whose
serializer is a separate type, use serialize_with.
§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::{ForyEnum, ForyStruct, ForyUnion};
#[derive(ForyStruct)]
struct Point { x: i32, y: i32 }
let mut fory = Fory::builder().xlang(true).build();
fory.register_by_name::<Point>("example.Point").unwrap();
let point = Point { x: 10, y: 20 };
let bytes = fory.serialize(&point).unwrap();Sourcepub fn serialize_with<S>(&self, record: &S::Target) -> Result<Vec<u8>, Error>where
S: Serializer,
pub fn serialize_with<S>(&self, record: &S::Target) -> Result<Vec<u8>, Error>where
S: Serializer,
Serializes a value using the explicitly selected serializer.
record must be exactly Serializer::Target for S. Register S
first when it is an independently registered structural or manual serializer. Fory-owned
carrier serializers compose their child serializers and are not registered.
Sourcepub fn serialize_to<T>(
&self,
buf: &mut Vec<u8>,
record: &T,
) -> Result<usize, Error>where
T: Serializer<Target = T>,
pub fn serialize_to<T>(
&self,
buf: &mut Vec<u8>,
record: &T,
) -> Result<usize, Error>where
T: Serializer<Target = T>,
Serializes a value of type T into the provided byte buffer.
This is for ordinary roots whose value type selects its own serializer
through T: Serializer<Target = T>. For an external target whose
serializer is a separate type, use
serialize_to_with.
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::{ForyEnum, ForyStruct, ForyUnion};
#[derive(ForyStruct)]
struct Point {
x: i32,
y: i32,
}
let mut fory = Fory::builder().xlang(true).build();
fory.register_by_name::<Point>("example.Point").unwrap();
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::{ForyEnum, ForyStruct, ForyUnion};
#[derive(ForyStruct, PartialEq, Debug)]
struct Point {
x: i32,
y: i32,
}
let mut fory = Fory::builder().xlang(true).build();
fory.register_by_name::<Point>("example.Point").unwrap();
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::{ForyEnum, ForyStruct, ForyUnion};
#[derive(ForyStruct)]
struct Point {
x: i32,
y: i32,
}
let mut fory = Fory::builder().xlang(true).build();
fory.register_by_name::<Point>("example.Point").unwrap();
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 serialize_to_with<S>(
&self,
buf: &mut Vec<u8>,
record: &S::Target,
) -> Result<usize, Error>where
S: Serializer,
pub fn serialize_to_with<S>(
&self,
buf: &mut Vec<u8>,
record: &S::Target,
) -> Result<usize, Error>where
S: Serializer,
Serializes a value into a buffer using the explicitly selected serializer.
This is the buffer-writing counterpart of serialize_with.
Sourcepub fn register<S: StructSerializer>(&mut self, id: u32) -> Result<(), Error>
pub fn register<S: StructSerializer>(&mut self, id: u32) -> Result<(), Error>
Registers a structural serializer with a numeric type ID.
This accepts ordinary and external structural serializers for structs and enum-category types.
§Type Parameters
S- The structural serializer to register.
§Arguments
id- A unique numeric identifier for the type. This ID is used in the serialized format to identify the type during deserialization.
§Errors
Returns an error when the serializer category, target, type ID, or another registration identity conflicts with an existing registration.
§Examples
use fory::Fory;
use fory::{ForyEnum, ForyStruct, ForyUnion};
#[derive(ForyStruct)]
struct User { name: String, age: u32 }
let mut fory = Fory::builder().xlang(true).build();
fory.register::<User>(100).unwrap();Sourcepub fn register_union<S: StructSerializer>(
&mut self,
id: u32,
) -> Result<(), Error>
pub fn register_union<S: StructSerializer>( &mut self, id: u32, ) -> Result<(), Error>
Registers an xlang-compatible union serializer with a numeric type ID.
The serializer may be generated by derive or by the schema compiler.
Sourcepub fn register_by_name<S: StructSerializer>(
&mut self,
name: &str,
) -> Result<(), Error>
pub fn register_by_name<S: StructSerializer>( &mut self, name: &str, ) -> Result<(), Error>
Registers a structural serializer with a qualified type name.
This accepts ordinary and external structural serializers for structs and enum-category types.
§Type Parameters
S- The structural serializer to register.
§Arguments
name- The type name, optionally prefixed with a namespace separated by.. For example,"com.example.User"uses namespace"com.example"and type name"User". Use"User"for the default namespace.
§Notes
This registration method is preferred for xlang serialization because it uses human-readable type identifiers instead of numeric IDs, which improves compatibility across different language implementations.
§Examples
The example uses xlang mode because name-based registration is the preferred registration style for cross-language payloads.
use fory::Fory;
use fory::{ForyEnum, ForyStruct, ForyUnion};
#[derive(ForyStruct)]
struct User { name: String, age: u32 }
let mut fory = Fory::builder().xlang(true).build();
fory.register_by_name::<User>("com.example.User").unwrap();Sourcepub fn register_union_by_name<S: StructSerializer>(
&mut self,
name: &str,
) -> Result<(), Error>
pub fn register_union_by_name<S: StructSerializer>( &mut self, name: &str, ) -> Result<(), Error>
Registers an xlang-compatible union serializer with a qualified name.
The serializer may be generated by derive or by the schema compiler.
Sourcepub fn register_serializer<S: Serializer>(
&mut self,
id: u32,
) -> Result<(), Error>
pub fn register_serializer<S: Serializer>( &mut self, id: u32, ) -> Result<(), Error>
Registers a manual serializer with a numeric type ID.
§Type Parameters
S- The manual EXT serializer to register. Unlikeregister(), this does not requireStructSerializer, making it suitable for non-struct types or types with manual serialization logic.
§Arguments
id- A unique numeric identifier for the type.
§Use Cases
Use this method for a manual serializer that declares the EXT wire category and implements opaque, hand-written serialization for its target.
§Examples
use fory_core::Fory;
let mut fory = Fory::builder().xlang(false).build();
fory.register_serializer::<UuidSerializer>(200).unwrap();Sourcepub fn register_serializer_by_name<S: Serializer>(
&mut self,
name: &str,
) -> Result<(), Error>
pub fn register_serializer_by_name<S: Serializer>( &mut self, name: &str, ) -> Result<(), Error>
Registers a manual serializer with a qualified type name.
§Type Parameters
S- The manual EXT serializer to register.
§Arguments
name- The type name, optionally prefixed with a namespace separated by..
§Notes
This is the named equivalent of register_serializer(), preferred for
xlang serialization scenarios.
Sourcepub fn write_head<S: Serializer>(&self, writer: &mut Writer<'_>)
pub fn write_head<S: Serializer>(&self, writer: &mut Writer<'_>)
Writes the serialization header to the writer.
Sourcepub fn deserialize<T>(&self, bf: &[u8]) -> Result<T, Error>where
T: Serializer<Target = T>,
pub fn deserialize<T>(&self, bf: &[u8]) -> Result<T, Error>where
T: Serializer<Target = T>,
Deserializes data from a byte slice into a value of type T.
§Type Parameters
T- A local target type whose serializer is selected by the type itself.
§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::{ForyEnum, ForyStruct, ForyUnion};
#[derive(ForyStruct)]
struct Point { x: i32, y: i32 }
let mut fory = Fory::builder().xlang(true).build();
fory.register_by_name::<Point>("example.Point").unwrap();
let point = Point { x: 10, y: 20 };
let bytes = fory.serialize(&point).unwrap();
let deserialized: Point = fory.deserialize(&bytes).unwrap();Sourcepub fn deserialize_with<S>(&self, bf: &[u8]) -> Result<S::Target, Error>where
S: Serializer,
pub fn deserialize_with<S>(&self, bf: &[u8]) -> Result<S::Target, Error>where
S: Serializer,
Deserializes a value using the explicitly selected serializer.
The result is exactly Serializer::Target for S. Its wire bytes must
have been written with the same serializer or a schema-compatible peer.
Sourcepub fn deserialize_from<T>(&self, reader: &mut Reader<'_>) -> Result<T, Error>where
T: Serializer<Target = T>,
pub fn deserialize_from<T>(&self, reader: &mut Reader<'_>) -> Result<T, Error>where
T: Serializer<Target = T>,
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- A local target type whose serializer is selected by the type itself.
§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::{ForyEnum, ForyStruct, ForyUnion};
#[derive(ForyStruct)]
struct Point { x: i32, y: i32 }
let mut fory = Fory::builder().xlang(true).build();
fory.register_by_name::<Point>("example.Point").unwrap();
let point = Point { x: 10, y: 20 };
let mut buf = Vec::new();
fory.serialize_to(&mut buf, &point).unwrap();
let mut reader = Reader::new(&buf);
let deserialized: Point = fory.deserialize_from(&mut reader).unwrap();Sourcepub fn deserialize_from_with<S>(
&self,
reader: &mut Reader<'_>,
) -> Result<S::Target, Error>where
S: Serializer,
pub fn deserialize_from_with<S>(
&self,
reader: &mut Reader<'_>,
) -> Result<S::Target, Error>where
S: Serializer,
Deserializes from a reader using the explicitly selected serializer.
This is the reader-based counterpart of deserialize_with.