#[derive(Byteable)]
{
// Attributes available to this derive:
#[byteable]
}
Expand description
Derives a delegate pattern for Byteable by generating a raw struct with endianness markers.
This macro creates a companion *Raw struct with #[repr(C, packed)] that handles the actual
byte conversion, while keeping your original struct clean and easy to work with. Fields can be
annotated with #[byteable(little_endian)] or #[byteable(big_endian)] to specify endianness.
§Generated Code
For each struct, this macro generates:
- A
*Rawstruct with#[repr(C, packed)]and endianness wrappers From<OriginalStruct>forOriginalStructRawimplementationFrom<OriginalStructRaw>forOriginalStructimplementation- A
Byteableimplementation viaimpl_byteable_via!macro
§Attributes
#[byteable(little_endian)]- Wraps the field inLittleEndian<T>#[byteable(big_endian)]- Wraps the field inBigEndian<T>#[byteable(transparent)]- Uses the field’s raw representation type directly (for nestedByteabletypes implementingByteableRaw)- No attribute - Keeps the field type as-is
§Requirements
- The struct must have named fields (not a tuple struct)
- Fields with endianness attributes must be numeric types that implement
EndianConvert - Fields with
transparentattribute must implementByteable - The struct should derive
CloneandCopyfor convenience
§Examples
§Basic usage
use byteable::Byteable;
#[derive(Clone, Copy, Byteable)]
struct Packet {
id: u8,
#[byteable(little_endian)]
length: u16,
#[byteable(big_endian)]
checksum: u32,
data: [u8; 4],
}
let packet = Packet {
id: 42,
length: 1024,
checksum: 0x12345678,
data: [1, 2, 3, 4],
};
// Byteable is automatically implemented
let bytes = packet.to_byte_array();
let restored = Packet::from_byte_array(bytes);§Generated code
The above example generates approximately:
ⓘ
#[derive(Clone, Copy, Debug, UnsafeByteableTransmute)]
#[repr(C, packed)]
struct PacketRaw {
id: u8,
length: LittleEndian<u16>,
checksum: BigEndian<u32>,
data: [u8; 4],
}
impl From<Packet> for PacketRaw {
fn from(value: Packet) -> Self {
Self {
id: value.id,
length: value.length.into(),
checksum: value.checksum.into(),
data: value.data,
}
}
}
impl From<PacketRaw> for Packet {
fn from(value: PacketRaw) -> Self {
Self {
id: value.id,
length: value.length.get(),
checksum: value.checksum.get(),
data: value.data,
}
}
}
impl_byteable_via!(Packet => PacketRaw);