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_typemust implementByteable$regular_typemust implementFrom<$raw_type>$raw_typemust implementFrom<$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);