Byteable
A Rust crate for zero-overhead, zero-copy serialization and deserialization of byte-oriented data.
byteable provides traits and utilities for seamless conversion between data structures and byte arrays, with full support for both synchronous and asynchronous I/O operations, and comprehensive endianness handling.
Features
- Byte Conversion Traits: Modular trait system for byte array conversion:
AssociatedByteArray: Associates a type with its byte array representationIntoByteArray: Converts values into byte arraysFromByteArray: Constructs values from byte arraysTryIntoByteArray&TryFromByteArray: Fallible conversion variants for types that can fail (e.g.,bool,char, enums)
ReadByteable&WriteByteable: Extension traits forstd::io::Readandstd::io::WriteAsyncReadByteable&AsyncWriteByteable: Async I/O support with tokio (optional)- Endianness Support:
BigEndian<T>andLittleEndian<T>wrappers for explicit byte order #[derive(Byteable)]: Procedural macro for automatic trait implementation with endianness support (optional)- Extensive Documentation: Every function, trait, and type is thoroughly documented with examples
- Inline Comments: All implementations include detailed explanatory comments
- Zero Overhead: Compiles down to simple memory operations with no runtime cost
Why byteable?
- Binary Protocols: Perfect for implementing network protocols (TCP, UDP, custom formats)
- File I/O: Read/write binary file formats with ease
- Cross-Platform: Consistent behavior across different architectures with endianness control
- Type-Safe: Rust's type system ensures correctness at compile time
- No Dependencies: Core functionality has zero dependencies (tokio is optional)
Installation
Add byteable to your Cargo.toml:
[]
= "0.19" # Or latest version
Optional Features
[]
= { = "0.19", = ["derive", "tokio"] }
derive(default): Enables the#[derive(Byteable)]procedural macrotokio: Enables async I/O traits for use with tokio
Quick Start
Basic File I/O Example
use ;
use File;
Network Protocol Example
use Byteable;
let header = TcpHeader ;
// Convert to bytes for transmission
let bytes = header.into_byte_array;
Async I/O with Tokio
use ;
use TcpStream;
async
Primitive Type Support
bool and char
The crate provides safe support for bool and char types with proper validation via TryFromByteArray. These types have restricted valid byte patterns and will return errors for invalid values.
Boolean Support
use ;
// Valid boolean values
let value = true;
let bytes = value.into_byte_array;
assert_eq!;
let value = false;
let bytes = value.into_byte_array;
assert_eq!;
// Roundtrip conversion
let restored = booltry_from_byte_array.unwrap;
assert_eq!;
// Invalid byte values return errors
let result = booltry_from_byte_array;
assert!; // Only 0 and 1 are valid
Character Support
Rust's char type represents a Unicode scalar value (code points U+0000 to U+10FFFF, excluding surrogates). Characters are stored as little-endian 32-bit integers.
use ;
// ASCII character
let ch = 'A';
let bytes = ch.into_byte_array;
assert_eq!; // Little-endian U+0041
// Unicode emoji
let ch = '🦀';
let bytes = ch.into_byte_array;
assert_eq!; // Little-endian U+1F980
// Roundtrip conversion
let restored = chartry_from_byte_array.unwrap;
assert_eq!;
// Invalid code points return errors
let result = chartry_from_byte_array;
assert!; // Not a valid Unicode scalar value
Using bool and char in Structs
use ;
Important Notes:
- Use
TryFromByteArrayinstead ofFromByteArrayfor types containingboolorchar boolonly accepts0(false) or1(true)charvalidates against Unicode scalar values (excludes surrogates and values > U+10FFFF)- Characters are always stored as little-endian 32-bit values
Enum Support
The #[derive(Byteable)] macro now supports C-like enums with explicit discriminants! This is perfect for encoding protocol status codes, command types, and other enumerated values in binary formats.
Basic Enum Usage
use ;
// Required: explicit repr type
Enum with Endianness
Enums support the same endianness attributes as structs:
use Byteable;
// Little-endian enum (common for file formats)
// Big-endian enum (common for network protocols)
Enum Requirements
When deriving Byteable for enums, you must ensure:
- Explicit repr type: Use
#[repr(u8)],#[repr(u16)],#[repr(u32)],#[repr(u64)],#[repr(i8)],#[repr(i16)],#[repr(i32)], or#[repr(i64)] - Unit variants only: All variants must be unit variants (no fields)
- Explicit discriminants: All variants must have explicit discriminant values
- Error handling: Use
TryFromByteArrayinstead ofFromByteArraysince invalid byte patterns return errors
Sparse Enums
Enums with non-sequential discriminants are fully supported:
use Byteable;
// Only the defined discriminants are valid
assert_eq!;
assert_eq!;
// Values 2, 3, 4, 6, 7, etc. will return errors
assert!;
Usage Patterns
Working with Different Endianness
use Byteable;
Reading Multiple Values
use ReadByteable;
use Cursor;
let data = vec!;
let mut reader = new;
let header: u32 = reader.read_byteable?;
let length: u16 = reader.read_byteable?;
let checksum: u32 = reader.read_byteable?;
Safety Considerations
The #[derive(Byteable)] macro uses unsafe code (core::mem::transmute) internally. When using it, you must ensure:
Safe to Use With:
- Primitive numeric types (
u8,i32,f64, etc.) boolandchar(with validation viaTryFromByteArray)BigEndian<T>andLittleEndian<T>wrappers- Arrays of safe types
- Structs with
#[repr(C, packed)]or#[repr(transparent)] - C-like enums with explicit discriminants (with validation via
TryFromByteArray)
Never Use With:
- Complex enums with fields (have invalid bit patterns)
String,Vec, or any heap-allocated types- References or pointers (
&T,Box<T>,*const T) - Types with
Dropimplementations NonZero*types or types with invariants
Requirements:
- Explicit memory layout: Always use
#[repr(C, packed)]or similar - All byte patterns valid: Every possible byte combination must be valid for your type
- No padding with undefined values: Use
packedto avoid alignment padding - No drop glue: Types must be
Copyand have no cleanup logic
Documentation
The crate includes extensive documentation:
- API Documentation: Every trait, type, and function is documented with examples
- Inline Comments: All implementations include explanatory comments
- Safety Guidelines: Clear warnings about unsafe usage
- Examples: Multiple real-world usage examples in the
examples/directory
Generate and view the documentation locally:
See Also
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Acknowledgments
Built with ❤️ for the Rust community.