#![no_std]
pub use byte_struct_derive::{ByteStruct, ByteStructBE, ByteStructLE};
pub trait ByteStructLen {
const BYTE_LEN: usize;
}
pub trait ByteStruct: ByteStructLen {
fn write_bytes(&self, bytes: &mut [u8]);
fn read_bytes(bytes: &[u8]) -> Self;
}
pub trait ByteStructUnspecifiedByteOrder: ByteStructLen {
fn write_bytes_default_le(&self, bytes: &mut [u8]);
fn read_bytes_default_le(bytes: &[u8]) -> Self;
fn write_bytes_default_be(&self, bytes: &mut [u8]);
fn read_bytes_default_be(bytes: &[u8]) -> Self;
}
impl<T: ByteStruct> ByteStructUnspecifiedByteOrder for T {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
self.write_bytes(bytes);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
Self::read_bytes(bytes)
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
self.write_bytes(bytes);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
Self::read_bytes(bytes)
}
}
impl ByteStructLen for u8 {
const BYTE_LEN: usize = 1;
}
impl ByteStructUnspecifiedByteOrder for u8 {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_le_bytes()[..]);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
u8::from_le_bytes([bytes[0]])
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_be_bytes()[..]);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
u8::from_be_bytes([bytes[0]])
}
}
impl ByteStructLen for i8 {
const BYTE_LEN: usize = 1;
}
impl ByteStructUnspecifiedByteOrder for i8 {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_le_bytes()[..]);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
i8::from_le_bytes([bytes[0]])
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_be_bytes()[..]);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
i8::from_be_bytes([bytes[0]])
}
}
impl ByteStructLen for u16 {
const BYTE_LEN: usize = 2;
}
impl ByteStructUnspecifiedByteOrder for u16 {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_le_bytes()[..]);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
u16::from_le_bytes([bytes[0], bytes[1]])
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_be_bytes()[..]);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
u16::from_be_bytes([bytes[0], bytes[1]])
}
}
impl ByteStructLen for i16 {
const BYTE_LEN: usize = 2;
}
impl ByteStructUnspecifiedByteOrder for i16 {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_le_bytes()[..]);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
i16::from_le_bytes([bytes[0], bytes[1]])
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_be_bytes()[..]);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
i16::from_be_bytes([bytes[0], bytes[1]])
}
}
impl ByteStructLen for u32 {
const BYTE_LEN: usize = 4;
}
impl ByteStructUnspecifiedByteOrder for u32 {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_le_bytes()[..]);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_be_bytes()[..]);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
}
}
impl ByteStructLen for i32 {
const BYTE_LEN: usize = 4;
}
impl ByteStructUnspecifiedByteOrder for i32 {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_le_bytes()[..]);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
i32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_be_bytes()[..]);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
i32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
}
}
impl ByteStructLen for u64 {
const BYTE_LEN: usize = 8;
}
impl ByteStructUnspecifiedByteOrder for u64 {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_le_bytes()[..]);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
u64::from_le_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
])
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_be_bytes()[..]);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
u64::from_be_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
])
}
}
impl ByteStructLen for i64 {
const BYTE_LEN: usize = 8;
}
impl ByteStructUnspecifiedByteOrder for i64 {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_le_bytes()[..]);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
i64::from_le_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
])
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_be_bytes()[..]);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
i64::from_be_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
])
}
}
impl ByteStructLen for u128 {
const BYTE_LEN: usize = 16;
}
impl ByteStructUnspecifiedByteOrder for u128 {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_le_bytes()[..]);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
u128::from_le_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
])
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_be_bytes()[..]);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
u128::from_be_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
])
}
}
impl ByteStructLen for i128 {
const BYTE_LEN: usize = 16;
}
impl ByteStructUnspecifiedByteOrder for i128 {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_le_bytes()[..]);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
i128::from_le_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
])
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_be_bytes()[..]);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
i128::from_be_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
])
}
}
impl ByteStructLen for f32 {
const BYTE_LEN: usize = 4;
}
impl ByteStructUnspecifiedByteOrder for f32 {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_bits().to_le_bytes()[..]);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
f32::from_bits(u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_bits().to_be_bytes()[..]);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
f32::from_bits(u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
}
}
impl ByteStructLen for f64 {
const BYTE_LEN: usize = 8;
}
impl ByteStructUnspecifiedByteOrder for f64 {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_bits().to_le_bytes()[..]);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
f64::from_bits(u64::from_le_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
]))
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
bytes.copy_from_slice(&self.to_bits().to_be_bytes()[..]);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
f64::from_bits(u64::from_le_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
]))
}
}
impl<T: ByteStructLen, const N: usize> ByteStructLen for [T; N] {
const BYTE_LEN: usize = N * T::BYTE_LEN;
}
impl<T: ByteStructUnspecifiedByteOrder, const N: usize> ByteStructUnspecifiedByteOrder for [T; N] {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
let mut pos = 0;
let len = T::BYTE_LEN;
for element in self {
element.write_bytes_default_le(&mut bytes[pos..pos + len]);
pos += len;
}
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
let len = T::BYTE_LEN;
core::array::from_fn(|i| <T>::read_bytes_default_le(&bytes[i * len..(i + 1) * len]))
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
let mut pos = 0;
let len = T::BYTE_LEN;
for element in self {
element.write_bytes_default_be(&mut bytes[pos..pos + len]);
pos += len;
}
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
let len = T::BYTE_LEN;
core::array::from_fn(|i| <T>::read_bytes_default_be(&bytes[i * len..(i + 1) * len]))
}
}
#[macro_export]
macro_rules! bitfields{
(
$(#[$outer:meta])*
$visibility:vis $name:ident : $base:ty {
$(
$(#[$inner:ident $($args:tt)*])*
$field_vis:vis $field_name:ident : $field_len:expr
),+ $(,)?
}
) => {
$(#[$outer])*
$visibility struct $name {
$(
$(#[$inner $($args)*])*
$field_vis $field_name: $base
),*
}
impl $name {
#[allow(unused_assignments)]
fn from_raw(raw: $base) -> $name {
let mut raw_v = raw;
$(
let mask: $base = (1 << $field_len) - 1;
let $field_name = raw_v & mask;
raw_v >>= $field_len;
)*
$name{$($field_name),*}
}
#[allow(unused_assignments)]
fn to_raw(&self) -> $base {
let mut raw: $base = 0;
let mut pos = 0;
$(
raw |= self.$field_name << pos;
pos += $field_len;
)*
raw
}
}
impl ByteStructLen for $name {
const BYTE_LEN: usize = <$base>::BYTE_LEN;
}
impl ByteStructUnspecifiedByteOrder for $name {
fn write_bytes_default_le(&self, bytes: &mut [u8]) {
self.to_raw().write_bytes_default_le(bytes);
}
fn read_bytes_default_le(bytes: &[u8]) -> Self {
<$name>::from_raw(<$base>::read_bytes_default_le(bytes))
}
fn write_bytes_default_be(&self, bytes: &mut [u8]) {
self.to_raw().write_bytes_default_be(bytes);
}
fn read_bytes_default_be(bytes: &[u8]) -> Self {
<$name>::from_raw(<$base>::read_bytes_default_be(bytes))
}
}
}
}