Skip to main content

Crate fory_core

Crate fory_core 

Source
Expand description

§Fory Core

This is the core implementation of the Fory serialization framework. It provides the fundamental building blocks for high-performance serialization and deserialization in Rust.

§Architecture

The core library is organized into several key modules:

  • fory: Main serialization engine and public API
  • buffer: Efficient binary buffer management with Reader/Writer
  • context: Per-operation read/write state and context pooling types
  • row: Row-based serialization for zero-copy operations
  • serializer: Type-specific serialization implementations
  • resolver: Type resolution and metadata management
  • meta: Metadata handling for schema evolution
  • types: Runtime value carriers such as temporal values, decimal, Float16, BFloat16, and weak refs
  • type_id: Type IDs and protocol header helpers
  • error: Error handling and result types
  • util: Utility functions and helpers

§Key Concepts

§Wire Modes And Schema Evolution

Fory supports two wire modes:

  • Xlang mode: the default cross-language wire format, selected with .xlang(true) and compatible schema evolution when compatible is omitted.
  • Native mode: the Rust-only wire format, selected with .xlang(false) with compatible schema evolution when compatible is omitted. Add .compatible(false) only when every reader and writer always uses the same schema and you need smaller, faster payloads.

§Type System

The framework uses a comprehensive type system that supports:

  • Primitive types (bool, integers, floats, strings)
  • Collections (Vec, HashMap, BTreeMap)
  • Optional types (Option<T>)
  • Date/time carriers with optional chrono integration
  • Custom structs and enums
  • Trait objects (Box, Rc, Arc)

§Performance Optimizations

  • Zero-copy deserialization in row mode
  • Buffer pre-allocation to minimize allocations
  • Variable-length encoding for compact representation
  • Little-endian byte order for cross-platform compatibility

§Trait Object Serialization

Fory supports polymorphic serialization through trait objects:

§Box-Based Trait Objects

Define custom traits and register implementations:

use fory_core::{Fory, register_trait_type, Serializer};
use fory_derive::{ForyEnum, ForyStruct, ForyUnion};

trait Animal: Serializer {
    fn speak(&self) -> String;
}

#[derive(ForyStruct, Debug)]
struct Dog { name: String }

#[derive(ForyStruct, Debug)]
struct Cat { name: String }

impl Animal for Dog {
    fn speak(&self) -> String { "Woof!".to_string() }
}

impl Animal for Cat {
    fn speak(&self) -> String { "Meow!".to_string() }
}

register_trait_type!(Animal, Dog, Cat);

#[derive(ForyStruct)]
struct Zoo {
    star_animal: Box<dyn Animal>,
}

let mut fory = Fory::builder().xlang(false).build();
fory.register::<Dog>(100).unwrap();
fory.register::<Cat>(101).unwrap();
fory.register::<Zoo>(102).unwrap();

let zoo = Zoo {
    star_animal: Box::new(Dog { name: "Buddy".to_string() }),
};

let bytes = fory.serialize(&zoo).unwrap();
let decoded: Zoo = fory.deserialize(&bytes).unwrap();
assert_eq!(decoded.star_animal.speak(), "Woof!");
§Rc/Arc-Based Trait Objects

For reference-counted trait objects, use them directly in struct fields:

#[derive(ForyStruct)]
struct Shelter {
    animals_rc: Vec<Rc<dyn Animal>>,
    animals_arc: Vec<Arc<dyn Animal>>,
}

For standalone serialization, use auto-generated wrapper types (e.g., AnimalRc, AnimalArc) created by register_trait_type! due to Rust’s orphan rule limitations.

§Usage

This crate is typically used through the higher-level fory crate, which provides derive macros and a more convenient API. However, you can use the core types directly for advanced use cases.

use fory_core::fory::Fory;
use fory_core::error::Error;
use fory_core::row::{to_row, from_row};
use std::collections::HashMap;

// Create a Fory instance
let mut fory = Fory::builder().xlang(false).build();

// Serialize String
let text = String::from("Hello, Fory!");
let serialized_str = fory.serialize(&text).unwrap();
let deserialized_str: String = fory.deserialize(&serialized_str).unwrap();
assert_eq!(text, deserialized_str);

// Serialize Vec
let vec_data = vec![1, 2, 3, 4, 5];
let serialized_vec = fory.serialize(&vec_data).unwrap();
let deserialized_vec: Vec<i32> = fory.deserialize(&serialized_vec).unwrap();
assert_eq!(vec_data, deserialized_vec);

// Serialize HashMap
let mut map = HashMap::new();
map.insert("key1".to_string(), 100);
map.insert("key2".to_string(), 200);
let serialized_map = fory.serialize(&map).unwrap();
let deserialized_map: HashMap<String, i32> = fory.deserialize(&serialized_map).unwrap();
assert_eq!(map, deserialized_map);
// Register types for object serialization
// fory.register::<MyStruct>(type_id);

// Use row-based serialization for zero-copy operations
// let row_data = to_row(&my_data);
// let row = from_row::<MyStruct>(&row_data);

Re-exports§

pub use crate::buffer::Reader;
pub use crate::buffer::Writer;
pub use crate::config::Config;
pub use crate::context::ReadContext;
pub use crate::context::WriteContext;
pub use crate::error::Error;
pub use crate::fory::Fory;
pub use crate::fory::ForyBuilder;
pub use crate::meta::compute_field_hash;
pub use crate::meta::compute_struct_hash;
pub use crate::resolver::RefFlag;
pub use crate::resolver::RefMode;
pub use crate::resolver::TypeInfo;
pub use crate::resolver::TypeResolver;
pub use crate::serializer::read_data;
pub use crate::serializer::write_data;
pub use crate::serializer::ForyDefault;
pub use crate::serializer::Serializer;
pub use crate::serializer::StructSerializer;
pub use crate::type_id::TypeId;
pub use crate::types::bfloat16::bfloat16 as BFloat16;
pub use crate::types::float16::float16 as Float16;
pub use crate::types::ArcWeak;
pub use crate::types::Date;
pub use crate::types::Decimal;
pub use crate::types::Duration;
pub use crate::types::RcWeak;
pub use crate::types::Timestamp;
pub use crate::types::UnknownCase;
pub use paste;

Modules§

buffer
config
context
error
PERFORMANCE CRITICAL MODULE
fory
meta
resolver
row
serializer
type_id
types
util

Macros§

bail
Returns early with an Error.
downcast_and_serialize
Helper macro for common type resolution and downcasting pattern
ensure
Ensures a condition is true; otherwise returns an Error.
generate_box_trait_codec
generate_smart_pointer_codec
generate_smart_pointer_wrapper
Unified macro to generate smart pointer wrapper types for traits Supports both Rc and Arc pointer types
impl_smart_pointer_serializer
Shared serializer implementation for smart pointer wrappers
impl_tuple_serializer
Macro to implement Serializer for tuples of various sizes. Fory supports tuples up to 22 elements, longer tuples are not allowed.
not_allowed
Returns early with a Error::NotAllowed.
read_ptr_trait_object
Macro to read smart pointer trait objects (Rc<dyn Trait>, Arc<dyn Trait>) This macro handles ref tracking and directly constructs the trait object from concrete types
register_trait_type
Macro to register trait object conversions for custom traits.
unwrap_rc
Convert wrapper back to Rc<dyn Trait> for deserialization
wrap_arc
Convert Arc<dyn Trait> to wrapper for serialization
wrap_rc
Helper macros for automatic conversions in derive code These are used by fory-derive to generate transparent conversions
wrap_vec_rc
Convert Vec<Rc<dyn Trait>> to Vec<wrapper> for serialization