Expand description
§Fory Derive Macros
This crate provides procedural macros for the Fory serialization framework.
It generates serialization and deserialization code for Rust types.
Most applications should import these macros from the fory facade crate,
which also provides the runtime API used by generated code. Direct
fory-derive usage is for crates that intentionally depend on the
lower-level fory-core runtime crate.
§Available Macros
§#[derive(ForyStruct)], #[derive(ForyEnum)], #[derive(ForyUnion)]
Generates Serializer implementations for structs, pure enums, and tagged
unions with payload variants.
Supported Types:
ForyStruct: named, tuple, and unit structsForyEnum: pure unit enumsForyUnion: enums with payload variants
Example:
use fory_derive::{ForyEnum, ForyStruct};
use std::collections::HashMap;
#[derive(ForyStruct, Debug, PartialEq)]
struct Person {
name: String,
age: i32,
address: Address,
hobbies: Vec<String>,
metadata: HashMap<String, String>,
}
#[derive(ForyStruct, Debug, PartialEq)]
struct Address {
street: String,
city: String,
}
#[derive(ForyEnum, Debug, PartialEq, Default)]
enum Status {
#[default]
Active,
Inactive,
Suspended,
}§#[derive(ForyRow)]
Generates Standard Row Format serialization and borrowed field views for a
named struct. The macro implements RowValue and the root Row marker.
Enums, unions, tuple structs, and unit structs are rejected at compile time.
Supported Types:
- Fixed values:
bool,i8,i16,i32,i64,f32,f64,Date,Timestamp, andDuration - Variable values:
Stringand&str, binaryVec<u8>and&[u8], fixed and variable arrays,BTreeMap, and other derived row structs Option<T>for nullable fields and array elements- Every field type must implement
RowValue
Example:
use fory_core::error::Error;
use fory_core::row::{from_row, to_row};
use fory_derive::ForyRow;
#[derive(ForyRow)]
struct UserProfile {
id: i64,
username: String,
email: Option<String>,
}
let bytes = to_row(&UserProfile {
id: 7,
username: "fory".to_owned(),
email: None,
})?;
let view = from_row::<UserProfile>(&bytes)?;
assert_eq!(view.id()?, 7);
assert_eq!(view.username()?, "fory");
assert_eq!(view.email()?, None);§Generated Code
§For #[derive(ForyStruct)], #[derive(ForyEnum)], and #[derive(ForyUnion)]
The macro generates:
Serializertrait implementation- Serialization methods for writing data to buffers
- Deserialization methods for reading data from buffers
- Type ID management for cross-language compatibility
§For #[derive(ForyRow)]
The macro generates:
- A
RowValueimplementation and a rootRowmarker implementation - A borrowed view type whose visibility matches the source struct
RowViewbacking-byte access and cheapCopy/Cloneviews- One declaration-order field method preserving each source field’s visibility
- Field methods returning
Result<<Field as RowValue>::View<'_>, Error>
§Attributes
#[fory(debug)]/#[fory(debug = true)]: Enables per-field debug instrumentation for the annotated struct, allowing you to install custom hooks viafory_core::serializer::struct_.#[fory(evolving = false)]: Disables compatible struct type IDs for the annotated struct, forcing STRUCT/NAMED_STRUCT even when compatible mode is enabled.#[fory(skip)]: Marks an individual field (or enum variant) to be ignored by the generated serializer, retaining compatibility with previous releases.#[fory(generate_default)]: Enables the macro to generateDefaultimplementation. By default,ForyStructdoes NOT generateimpl Defaultto avoid conflicts with existingDefaultimplementations. This attribute is not valid withtarget.#[fory(target = path::Type)]: Makes the derived declaration an external structural serializer for the target type. Generated code accesses and constructs the target directly; the serializer declaration itself is never instantiated.#[fory(with = SerializerType)]: Selects a serializer whose target is the exact field value node. Use carrier serializers for exact wrapper or container nodes, and uselist,map, ortuplemetadata to select serializers recursively at child nodes.#[fory(default)]: Marks the fallible deserialization defaultForyUnionvariant.ForyUnionrequires exactly one default variant.
§Field Types
The object-format derives support a wide range of field types:
Primitive Types:
bool,i8,i16,i32,i64,f32,f64StringVec<u8>for binary data
Collections:
Vec<T>whereTimplements the appropriate traitHashMap<K, V>andBTreeMap<K, V>where keys and values implement the traitOption<T>for nullable values
Date/Time:
fory::Datefory::Timestampfory::Durationchrono::NaiveDate,chrono::NaiveDateTime, andchrono::Durationwhen thechronofeature is enabled
Custom Types:
- Any type that implements
Serializer
ForyRow uses the separate, exact type set documented under its macro
section. A row field implements RowValue; only derived structs, arrays,
and maps implement the root Row marker.
Derived structs, enums, and unions can be used behind
Arc<dyn Any + Send + Sync> when the concrete type satisfies Send + Sync.
Known non-Send + Sync field types such as Rc<T> and RefCell<T> are not
eligible for that carrier.
§Usage with Fory
After deriving the macros, you can use the types with the Fory serialization framework:
use fory_core::{fory::Fory, error::Error};
use fory_derive::{ForyEnum, ForyStruct, ForyUnion};
#[derive(ForyStruct, Debug, PartialEq)]
struct MyData {
value: i32,
text: String,
}
fn main() -> Result<(), Error> {
let mut fory = Fory::builder().xlang(true).build();
fory.register_by_name::<MyData>("example.MyData")?;
let data = MyData {
value: 42,
text: "Hello, Fory!".to_string(),
};
let serialized = fory.serialize(&data)?;
let deserialized: MyData = fory.deserialize(&serialized)?;
assert_eq!(data, deserialized);
Ok(())
}§Performance Considerations
Fory: Best for complex object graphs with references and nested structuresForyRow: Provides lazy, borrowed access to Standard Row Format data- Both macros generate optimized code with minimal runtime overhead
Derive Macros§
- Fory
Enum - Derive macro for pure enum serialization.
- ForyRow
- Derive macro for Standard Row Format serialization.
- Fory
Struct - Derive macro for struct serialization.
- Fory
Union - Derives serialization for data-carrying Rust enums.