10 breaking releases
Uses new Rust 2024
| 0.12.0 | Jan 8, 2026 |
|---|---|
| 0.10.0 | Jan 3, 2026 |
| 0.9.1 | Dec 28, 2025 |
| 0.1.0 | Sep 29, 2025 |
#9 in #byte-conversion
Used in byteable
52KB
675 lines
byteable_derive
This crate provides custom derive macros for the byteable crate.
Available Derives
#[derive(Byteable)]
The main derive macro that automatically implements byte conversion traits for your types. Supports:
- Structs (named, tuple, and unit structs)
- Enums (C-like enums with explicit discriminants)
- Endianness control via field and type-level attributes
- Nested byteable types via
transparentandtry_transparentattributes
Struct Support
Basic Struct
use byteable::Byteable;
#[derive(Byteable, Clone, Copy)]
struct Point {
x: i32,
y: i32,
}
Struct with Endianness
use byteable::Byteable;
#[derive(Byteable, Clone, Copy)]
struct NetworkPacket {
version: u8,
#[byteable(big_endian)]
length: u16,
#[byteable(little_endian)]
checksum: u32,
}
Field Attributes
#[byteable(big_endian)]- Store field in big-endian byte order#[byteable(little_endian)]- Store field in little-endian byte order#[byteable(transparent)]- Use field's raw representation (for nestedByteabletypes)#[byteable(try_transparent)]- Use field's raw representation with fallible conversion
Enum Support
The #[derive(Byteable)] macro supports C-like enums with explicit discriminants.
Basic Enum
use byteable::Byteable;
#[derive(Byteable, Debug, Clone, Copy, PartialEq)]
#[repr(u8)]
enum Status {
Idle = 0,
Running = 1,
Completed = 2,
Failed = 3,
}
Enum with Endianness
Enums support type-level endianness attributes:
use byteable::Byteable;
// Little-endian (for file formats)
#[derive(Byteable, Debug, Clone, Copy, PartialEq)]
#[repr(u16)]
#[byteable(little_endian)]
enum FileType {
Text = 0x1000,
Binary = 0x2000,
Archive = 0x3000,
}
// Big-endian (for network protocols)
#[derive(Byteable, Debug, Clone, Copy, PartialEq)]
#[repr(u32)]
#[byteable(big_endian)]
enum HttpStatus {
Ok = 200,
NotFound = 404,
InternalError = 500,
}
Enum Requirements
When deriving Byteable for enums, you must:
- Use an explicit repr type:
#[repr(u8)],#[repr(u16)],#[repr(u32)],#[repr(u64)],#[repr(i8)],#[repr(i16)],#[repr(i32)], or#[repr(i64)] - Have only unit variants (no fields)
- Provide explicit discriminant values for all variants
- Use
TryFromByteArrayfor deserialization (returnsEnumFromBytesErrorfor invalid discriminants)
Type-Level Attributes for Enums
#[byteable(big_endian)]- Store enum discriminant in big-endian byte order#[byteable(little_endian)]- Store enum discriminant in little-endian byte order- No attribute - Use native endianness
Error Handling
Enums use fallible conversion because not all byte patterns represent valid enum variants:
use byteable::{Byteable, TryFromByteArray};
#[derive(Byteable, Debug, Clone, Copy, PartialEq)]
#[repr(u8)]
enum Command {
Start = 1,
Stop = 2,
}
fn example() -> Result<(), byteable::EnumFromBytesError> {
// Valid conversion
let bytes = [1];
let cmd = Command::try_from_byte_array(bytes)?;
assert_eq!(cmd, Command::Start);
// Invalid discriminant returns error
let invalid = [255];
let result = Command::try_from_byte_array(invalid);
assert!(result.is_err());
Ok(())
}
Advanced Usage
Nested Structs with Enums
use byteable::Byteable;
#[derive(Byteable, Debug, Clone, Copy, PartialEq)]
#[repr(u8)]
enum MessageType {
Data = 1,
Control = 2,
Error = 3,
}
#[derive(Byteable, Clone, Copy)]
struct Message {
#[byteable(try_transparent)]
msg_type: MessageType,
#[byteable(big_endian)]
sequence: u32,
payload: [u8; 16],
}
Sparse Discriminants
Enums with non-sequential discriminants work perfectly:
use byteable::Byteable;
#[derive(Byteable, Debug, Clone, Copy, PartialEq)]
#[repr(u8)]
enum Priority {
Low = 1,
Medium = 5,
High = 10,
Critical = 100,
}
// Only defined discriminants (1, 5, 10, 100) are valid
// All other values return errors during conversion
See Also
For comprehensive documentation and examples, see the main byteable crate documentation.
Dependencies
~2.1–2.8MB
~66K SLoC