| Crates.io | flat_message |
| lib.rs | flat_message |
| version | 0.1.0 |
| created_at | 2025-10-11 13:03:39.25435+00 |
| updated_at | 2025-10-11 13:03:39.25435+00 |
| description | Zero-copy, schema-less serialization and deserialization fast library for Rust. |
| homepage | |
| repository | https://github.com/gdt050579/FlatMessage |
| max_upload_size | |
| id | 1878173 |
| size | 106,411 |
FlatMessage is a zero-copy, schema-less serialization library built for Rust, offering efficient and flexible data serialization with exceptional performance and rich type support.
&str, &[T], and &[u8; N] typesVec<T>, deserialize as &[T] (and vice versa)FlatMessage consistently outperforms other serialization libraries across different data structures:
| Library | Type | Throughput (MB/sec) | Notes |
|---|---|---|---|
| FlatMessage ⚡ | Schema-less | 4,624 - 6,705 | (⚡) = Unchecked deserialization |
| FlatMessage | Schema-less | 3,889 - 5,073 | With validation |
| protobuf | Schema-based | 2,261 - 2,799 | |
| postcard | Schema-based | 2,213 - 2,960 | |
| bincode | Schema-based | 2,025 - 2,323 | |
| flexbuffers | Schema-less | 410 - 582 | |
| JSON | Schema-less | 342 - 479 |
Averaged across Windows, macOS, and Linux on multiple test structures More details in the performance benchmarks.
Add FlatMessage to your Cargo.toml:
[dependencies]
flat_message = "*"
use flat_message::*;
#[derive(FlatMessage, Debug, PartialEq)]
struct Person {
name: String,
age: u32,
email: String,
}
fn main() -> Result<(), Error> {
// Create and serialize
let person = Person {
name: "Alice".to_string(),
age: 30,
email: "alice@example.com".to_string(),
};
let mut storage = Storage::default();
person.serialize_to(&mut storage, Config::default())?;
// Deserialize
let restored = Person::deserialize_from(&storage)?;
assert_eq!(person, restored);
println!("Serialized {} bytes", storage.len());
Ok(())
}
use flat_message::*;
#[derive(FlatMessage)]
struct Message<'a> {
title: &'a str, // Zero-copy string reference
tags: &'a [u32], // Zero-copy slice reference
metadata: &'a [u8], // Zero-copy byte slice
}
#[derive(FlatMessage)]
struct MessageOwned {
title: String,
tags: Vec<u32>,
metadata: Vec<u8>,
}
fn zero_copy_example() -> Result<(), Error> {
// Serialize with owned data
let owned_data = MessageOwned {
title: "Hello World".to_string(),
tags: vec![1, 2, 3, 4, 5],
metadata: vec![0xFF, 0xFE, 0xFD],
};
let mut storage = Storage::default();
owned_data.serialize_to(&mut storage, Config::default())?;
// Deserialize with zero-copy references
let message = Message::deserialize_from(&storage)?;
// No data copying - direct buffer access!
println!("Title: {}", message.title); // Points into storage
println!("Tags: {:?}", message.tags); // Points into storage
println!("Metadata: {:?}", message.metadata); // Points into storage
Ok(())
}
Seamlessly convert between owned and borrowed types:
#[derive(FlatMessage)]
struct DataWriter {
numbers: Vec<u32>, // Owned data for writing
text: String,
}
#[derive(FlatMessage)]
struct DataReader<'a> {
numbers: &'a [u32], // Zero-copy reference for reading
text: &'a str,
}
// Serialize with Vec, deserialize as slice - automatic conversion!
#[derive(FlatMessage)]
#[flat_message_options(version = 2, compatible_versions = "1,2")]
struct UserProfile {
name: String,
email: String,
// New field - optional for backward compatibility
age: Option<u32>,
}
// Can deserialize data from version 1 (age will be None)
// Can deserialize data from version 2 (age will be Some(value))
FlatMessage supports a rich type system, including:
#[derive(FlatMessage, Debug, Eq, PartialEq)]
struct ComplexData<'a> {
// Basic types
active: bool,
score: u32,
// unique message id
id: UniqueID,
// message timestamp
timestamp: Timestamp,
// Strings and vectors
name: &'a str,
tags: Vec<String>,
// Optional fields
description: Option<String>,
// Enums and variants
#[flat_message_item(repr = u8, kind = enum)]
status: Status,
#[flat_message_item(align = 1, kind = variant)]
data: DataVariant,
// Nested structures
#[flat_message_item(align = 4, kind = struct)]
metadata: Metadata,
}
#[derive(FlatMessageEnum, Copy, Clone, Debug, Eq, PartialEq)]
#[repr(u8)]
enum Status {
Active = 1,
Inactive = 2,
Pending = 3,
}
#[derive(FlatMessageVariant, Debug, Eq, PartialEq)]
enum DataVariant {
Text(String),
Number(i64),
Binary(Vec<u8>),
}
#[derive(FlatMessageStruct, Debug, Eq, PartialEq)]
struct Metadata {
author: String,
country: String,
}
Remarks: UniqueID and Timestamp are metadata fields and can be used only once for each struct.
More details in the Supported Data Types chapter.
FlatMessage excels in scenarios requiring:
| Library | Size | Ser+Deser Time | Performance |
|---|---|---|---|
| FlatMessage ⚡ | 26b (+225%) | 3.76ms | 🥇 Fastest |
| FlatMessage | 26b (+225%) | 4.49ms | 🥈 |
| postcard (schema) | 3b (-63%) | 6.95ms | |
| bincode (schema) | 2b (-75%) | 7.07ms |
| Library | Size | Ser+Deser Time | Performance |
|---|---|---|---|
| FlatMessage ⚡ | 355b (+69%) | 23.54ms | 🥇 Fastest |
| FlatMessage | 355b (+69%) | 27.36ms | 🥈 |
| bincode (schema) | 172b (-19%) | 39.87ms | |
| postcard (schema) | 154b (-27%) | 42.47ms |
| Library | Size | Ser+Deser Time | Performance |
|---|---|---|---|
| FlatMessage ⚡ | 3968b (+1%) | 28.22ms | 🥇 Fastest |
| postcard (schema) | 3915b (-1%) | 39.55ms | |
| FlatMessage | 3968b (+1%) | 40.63ms | 🥈 |
Results from Windows benchmarks. See full performance results for all platforms.
| Type | Zero-Copy | Memory Usage | Performance |
|---|---|---|---|
&str |
✅ Yes | Low | Fastest |
&[T] |
✅ Yes | Low | Fastest |
&[u8; N] |
✅ Yes | Low | Fastest |
String |
❌ No | High | Slower (allocation) |
Vec<T> |
❌ No | High | Slower (allocation) |
Option<&str> |
✅ Yes (when Some) | Low | Fast |
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
This project is licensed under the MIT License - see the LICENSE file for details.
Ready to supercharge your serialization? Add FlatMessage to your project today and experience the performance difference!