impl_byteable_via

Macro impl_byteable_via 

Source
macro_rules! impl_byteable_via {
    ($regular_type:ty => $raw_type:ty) => { ... };
}
Expand description

Implements Byteable for a type by delegating to another type.

This macro is useful when you have a “user-friendly” type and a “raw” type that can be converted between each other. The raw type must already implement Byteable, and both types must implement From for converting between them.

This pattern is common when you want to separate concerns:

  • The raw type handles byte layout (with endianness markers, packed representation)
  • The user-facing type provides a convenient API (with native types, methods)

§Requirements

  • $raw_type must implement Byteable
  • $regular_type must implement From<$raw_type>
  • $raw_type must implement From<$regular_type>

§Examples

use byteable::{Byteable, LittleEndian, impl_byteable_via, IntoByteArray, FromByteArray};

use byteable::UnsafeByteableTransmute;

// Raw type with explicit byte layout
#[derive(byteable::UnsafeByteableTransmute, Clone, Copy)]
#[repr(C, packed)]
struct PointRaw {
    x: LittleEndian<i32>,
    y: LittleEndian<i32>,
}

// User-friendly type
#[derive(Debug, PartialEq, Clone, Copy)]
struct Point {
    x: i32,
    y: i32,
}

// Implement conversions
impl From<Point> for PointRaw {
    fn from(p: Point) -> Self {
        Self {
            x: p.x.into(),
            y: p.y.into(),
        }
    }
}

impl From<PointRaw> for Point {
    fn from(raw: PointRaw) -> Self {
        Self {
            x: raw.x.get(),
            y: raw.y.get(),
        }
    }
}

// Now Point implements Byteable via PointRaw
impl_byteable_via!(Point => PointRaw);

let point = Point { x: 100, y: 200 };
let bytes = point.into_byte_array();
let restored = Point::from_byte_array(bytes);
assert_eq!(restored, point);