title: Basic Serialization sidebar_position: 1 id: basic_serialization license: | Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
This page covers basic object graph serialization and supported types.
Apache Fory™ provides automatic serialization of complex object graphs, preserving the structure and relationships between objects. The #[derive(ForyStruct)] macro generates efficient serialization code at compile time, eliminating reflection overhead.
Key capabilities:
Option<T>use fory::{Fory, Error}; use fory::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, country: String, } let mut fory = Fory::builder().xlang(true).build(); fory.register_by_name::<Address>("example.Address").unwrap(); fory.register_by_name::<Person>("example.Person").unwrap(); let person = Person { name: "John Doe".to_string(), age: 30, address: Address { street: "123 Main St".to_string(), city: "New York".to_string(), country: "USA".to_string(), }, hobbies: vec!["reading".to_string(), "coding".to_string()], metadata: HashMap::from([ ("role".to_string(), "developer".to_string()), ]), }; let bytes = fory.serialize(&person).unwrap(); let decoded: Person = fory.deserialize(&bytes)?; assert_eq!(person, decoded);
| Rust Type | Description |
|---|---|
bool | Boolean |
i8, i16, i32, i64 | Signed integers |
f32, f64 | Floating point |
BFloat16 | 16-bit brain floating point |
String | UTF-8 string |
| Rust Type | Description |
|---|---|
Vec<T> | Dynamic array |
VecDeque<T> | Double-ended queue |
LinkedList<T> | Doubly-linked list |
HashMap<K, V> | Hash map |
BTreeMap<K, V> | Ordered map |
HashSet<T> | Hash set |
BTreeSet<T> | Ordered set |
BinaryHeap<T> | Binary heap |
Option<T> | Optional value |
Vec<BFloat16> is the dense carrier when the schema is array<bfloat16>.
| Rust Type | Description |
|---|---|
Box<T> | Heap allocation |
Rc<T> | Reference counting (shared refs tracked) |
Arc<T> | Thread-safe reference counting (shared refs tracked) |
RcWeak<T> | Weak reference to Rc<T> (breaks circular refs) |
ArcWeak<T> | Weak reference to Arc<T> (breaks circular refs) |
RefCell<T> | Interior mutability (runtime borrow checking) |
Mutex<T> | Thread-safe interior mutability |
| Rust Type | Description |
|---|---|
Date | Date without timezone, stored as epoch days |
Timestamp | Point in time, stored as epoch seconds and nanos |
Duration | Signed duration, stored as seconds and normalized nanos |
The built-in carriers expose dependency-free constructors, accessors, conversions, and checked arithmetic:
use fory::{Date, Duration, Timestamp}; let date = Date::from_epoch_days(19_782); assert_eq!(date.checked_add_days(1)?.epoch_days(), 19_783); let timestamp = Timestamp::from_epoch_millis(-1); assert_eq!(timestamp.to_epoch_millis()?, -1); let duration = Duration::from_parts(1, 1_500_000_000)?; assert_eq!(duration.to_millis()?, 2_500); let later = timestamp.checked_add_duration(duration)?;
chrono::NaiveDate, chrono::NaiveDateTime, and chrono::Duration are supported when the Rust chrono feature is enabled:
[dependencies] fory = { version = "1.3.0", features = ["chrono"] }
| Macro | Description |
|---|---|
#[derive(ForyStruct)] | Object graph serialization |
#[derive(ForyRow)] | Row-based serialization |
use fory::{Fory, Reader}; let mut fory = Fory::builder().xlang(true).build(); fory.register::<MyStruct>(1)?; let obj = MyStruct { /* ... */ }; // Basic serialize/deserialize let bytes = fory.serialize(&obj)?; let decoded: MyStruct = fory.deserialize(&bytes)?; // Serialize to existing buffer let mut buf: Vec<u8> = vec![]; fory.serialize_to(&mut buf, &obj)?; // Deserialize from reader let mut reader = Reader::new(&buf); let decoded: MyStruct = fory.deserialize_from(&mut reader)?;