| Crates.io | byten |
| lib.rs | byten |
| version | 0.0.13 |
| created_at | 2025-10-30 20:57:49.955248+00 |
| updated_at | 2025-11-09 16:57:42.779516+00 |
| description | A binary codec library for efficient encoding and decoding of data structures |
| homepage | https://github.com/m-ali-akbay/byten |
| repository | https://github.com/m-ali-akbay/byten |
| max_upload_size | |
| id | 1908960 |
| size | 114,055 |
A binary codec library for efficient encoding and decoding of Rust data structures.
⚠️ Early Development: This library is in active development and the API may change.
Encode, Decode, Measure)Vec, arrays, slices with configurable length prefixesCStr), and byte slices'encoded lifetime)Add to your Cargo.toml:
[dependencies]
byten = "0.0"
use byten::{DefaultCodec, DecodeOwned, Encode, Measure, EncodeToVec as _};
#[derive(Debug, DefaultCodec, Encode, Measure, DecodeOwned, PartialEq)]
struct Person {
#[byten($be)]
id: u32,
age: u8,
#[byten($bytes[u8] $utf8 $own)]
name: String,
}
fn main() {
let person = Person {
id: 12345,
age: 30,
name: "Alice".to_string(),
};
// Encode to Vec
let encoded = person.encode_to_vec().unwrap();
// Decode from slice
let mut offset = 0;
let decoded = Person::decode(&encoded, &mut offset).unwrap();
assert_eq!(person, decoded);
}
use byten::{DefaultCodec, Decode, Encode, Measure, EncodeToVec as _};
use std::ffi::CStr;
#[derive(Debug, DefaultCodec, Encode, Decode, Measure)]
pub struct Person<'encoded> {
pub first_name: &'encoded CStr,
pub last_name: &'encoded CStr,
#[byten($bytes[u16 $be] $utf8)]
pub address: &'encoded str,
#[byten($bytes[u32 $uvarbe])]
pub avatar_image: &'encoded [u8],
#[byten(.. $utf8)]
pub extra_data: &'encoded str,
}
use byten::{DefaultCodec, DecodeOwned, Encode, Measure};
#[derive(Debug, DefaultCodec, DecodeOwned, Encode, Measure, PartialEq)]
#[repr(u16)]
#[byten($le)]
enum Color {
Red = 1,
Green = 2,
Blue = 3,
Grayscale(#[byten($be)] u16) = 4,
RGBa {
red: u8,
green: u8,
blue: u8,
#[byten($be)]
alpha: u16,
} = 5,
Gradient(Box<Color>, Box<Color>) = 6,
}
use byten::{DefaultCodec, DecodeOwned, Encode, Measure};
use std::ffi::CString;
#[derive(Debug, DefaultCodec, Encode, Measure, DecodeOwned)]
pub struct Directory {
#[byten(CStr $own)]
pub name: CString,
#[byten(Entry box for[u16 $be])]
pub entries: Vec<Box<Entry>>,
}
#[derive(Debug, DefaultCodec, Encode, Measure, DecodeOwned)]
pub struct File {
#[byten(CStr $own)]
pub name: CString,
#[byten($bytes[u16 $be] $own)]
pub content: Vec<u8>,
#[byten(u32 $be ?)]
pub assigned_application_id: Option<u32>,
}
#[derive(Debug, DefaultCodec, Encode, Measure, DecodeOwned)]
#[repr(u8)]
pub enum Entry {
File(File) = 1,
Directory(Directory) = 2,
}
use byten::{byten, Decoder, EncoderToVec as _};
fn main() {
// Define codec inline without derive macros
let codec = byten!( $bytes[u32 $be] $utf8 );
let original_str = "Hello, Byten!";
let encoded = codec.encode_to_vec(original_str).unwrap();
let decoded_str = codec.decode(&encoded, &mut 0).unwrap();
}
The #[byten(...)] attribute supports a flexible syntax for customizing encoding:
$be (big-endian), $le (little-endian)$uvarbe (variable-length unsigned, big-endian)T for[Length], T []$bytes[Length] for raw byte slices$utf8 for UTF-8 strings, CStr for C strings$own to decode into owned data (e.g., String, Vec)? for Option<T> types with presence bytebox for Box<T> types= expr for constant values with zero bytes.. to consume rest of input(a, b, ...N) as built-in codecs for N sized tuples{ expr } for custom codec expressionsstd (default): Enable standard library support. Disable for no_std environments with default-features = falsealloc (default via std): Enable types that require allocation (Vec, Box, String). Can be used in no_std with an allocator.anyhow (default): Integration with the anyhow error handling crate (requires std)derive (default): Enable derive macros for self-coded traits. Works in all modes (core-only, alloc, std).no_std EnvironmentsFor embedded systems without an allocator, use only core types:
[dependencies]
byten = { version = "0.0", default-features = false }
This provides support for:
u8, i8, bool, etc.)&str, &[u8], &CStr)With derive macros:
[dependencies]
byten = { version = "0.0", default-features = false, features = ["derive"] }
Note: When using derive macros in core-only mode, avoid using Vec, Box, String, or other allocation-dependent types in your structs.
For no_std environments with an allocator:
[dependencies]
byten = { version = "0.0", default-features = false, features = ["alloc"] }
This adds support for:
Vec<T> collectionsBox<T> heap allocationString)UVarBECodec)With derive macros (recommended for most use cases):
[dependencies]
byten = { version = "0.0", default-features = false, features = ["alloc", "derive"] }
Note: The derive feature works in all modes (core-only, alloc, and std). The generated code will only use features that are enabled.
The byten/examples directory contains several complete examples:
array.rs: Encoding arrays with variable-length integersborrowed.rs: Zero-copy decoding with borrowed data and lifetimesarchive.rs: Recursive structures (file system directory tree)icmp.rs: Network packet encoding (ICMP header)nostd.rs: Simple FS structures for no_std environmentsinline.rs: Using the inline byten!() macro for ad-hoc codecsRun examples with:
cargo run --example borrowed
Licensed under either of:
at your option.
Contributions are welcome! Please read our Contributing Guidelines for details on how to submit pull requests, report issues, and contribute to the project.
This project adheres to the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.