title: Rust Serialization Guide sidebar_position: 0 id: rust_serialization_index 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

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Apache Foryβ„’ is a blazing fast multi-language serialization framework powered by JIT compilation and zero-copy techniques, providing up to ultra-fast performance while maintaining ease of use and safety.

The Rust implementation provides versatile and high-performance serialization with automatic memory management and compile-time type safety.

Why Apache Foryβ„’ Rust?

  • πŸ”₯ Blazingly Fast: Zero-copy deserialization and optimized binary protocols
  • 🌍 Cross-Language: Seamlessly serialize/deserialize data across Java, Python, C++, Go, JavaScript, and Rust
  • 🎯 Type-Safe: Compile-time type checking with derive macros
  • πŸ”„ Circular References: Automatic tracking of shared and circular references with Rc/Arc and weak pointers
  • 🧬 Polymorphic: Serialize trait objects with Box<dyn Trait>, Rc<dyn Trait>, and Arc<dyn Trait>
  • πŸ“¦ Schema Evolution: Compatible mode for independent schema changes
  • ⚑ Two Formats: Object graph serialization and zero-copy row-based format

Crates

CrateDescriptionVersion
foryHigh-level API with derive macroscrates.io
fory-coreCore serialization enginecrates.io
fory-deriveProcedural macroscrates.io

Quick Start

Add Apache Foryβ„’ to your Cargo.toml:

[dependencies]
fory = "0.13"

Basic Example

use fory::{Fory, Error, Reader};
use fory::ForyObject;

#[derive(ForyObject, Debug, PartialEq)]
struct User {
    name: String,
    age: i32,
    email: String,
}

fn main() -> Result<(), Error> {
    let mut fory = Fory::default();
    fory.register::<User>(1)?;

    let user = User {
        name: "Alice".to_string(),
        age: 30,
        email: "alice@example.com".to_string(),
    };

    // Serialize
    let bytes = fory.serialize(&user)?;
    // Deserialize
    let decoded: User = fory.deserialize(&bytes)?;
    assert_eq!(user, decoded);

    // Serialize to specified buffer
    let mut buf: Vec<u8> = vec![];
    fory.serialize_to(&mut buf, &user)?;
    // Deserialize from specified buffer
    let mut reader = Reader::new(&buf);
    let decoded: User = fory.deserialize_from(&mut reader)?;
    assert_eq!(user, decoded);
    Ok(())
}

Thread Safety

Apache Foryβ„’ Rust is fully thread-safe: Fory implements both Send and Sync, so one configured instance can be shared across threads for concurrent work. The internal read/write context pools are lazily initialized with thread-safe primitives, letting worker threads reuse buffers without coordination.

use fory::{Fory, Error};
use fory::ForyObject;
use std::sync::Arc;
use std::thread;

#[derive(ForyObject, Clone, Copy, Debug, PartialEq)]
struct Item {
    value: i32,
}

fn main() -> Result<(), Error> {
    let mut fory = Fory::default();
    fory.register::<Item>(1000)?;

    let fory = Arc::new(fory);
    let handles: Vec<_> = (0..8)
        .map(|i| {
            let shared = Arc::clone(&fory);
            thread::spawn(move || {
                let item = Item { value: i };
                shared.serialize(&item)
            })
        })
        .collect();

    for handle in handles {
        let bytes = handle.join().unwrap()?;
        let item: Item = fory.deserialize(&bytes)?;
        assert!(item.value >= 0);
    }

    Ok(())
}

Tip: Perform registrations (such as fory.register::<T>(id)) before spawning threads so every worker sees the same metadata. Once configured, wrapping the instance in Arc is enough to fan out serialization and deserialization tasks safely.

Architecture

The Rust implementation consists of three main crates:

fory/                   # High-level API
β”œβ”€β”€ src/lib.rs         # Public API exports

fory-core/             # Core serialization engine
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ fory.rs       # Main serialization entry point
β”‚   β”œβ”€β”€ buffer.rs     # Binary buffer management
β”‚   β”œβ”€β”€ serializer/   # Type-specific serializers
β”‚   β”œβ”€β”€ resolver/     # Type resolution and metadata
β”‚   β”œβ”€β”€ meta/         # Meta string compression
β”‚   β”œβ”€β”€ row/          # Row format implementation
β”‚   └── types.rs      # Type definitions

fory-derive/           # Procedural macros
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ object/       # ForyObject macro
β”‚   └── fory_row.rs  # ForyRow macro

Use Cases

Object Serialization

  • Complex data structures with nested objects and references
  • Cross-language communication in microservices
  • General-purpose serialization with full type safety
  • Schema evolution with compatible mode
  • Graph-like data structures with circular references

Row-Based Serialization

  • High-throughput data processing
  • Analytics workloads requiring fast field access
  • Memory-constrained environments
  • Real-time data streaming applications
  • Zero-copy scenarios

Next Steps