Crates.io | endian-writer-derive |
lib.rs | endian-writer-derive |
version | 0.1.0 |
source | src |
created_at | 2024-10-27 22:04:03.83779 |
updated_at | 2024-10-27 22:04:03.83779 |
description | Procedural Macros for endian-writer crate. |
homepage | |
repository | https://github.com/Sewer56/endian-writer-derive |
max_upload_size | |
id | 1425067 |
size | 12,295 |
Procedural Macros for endian-writer crate (version 2.X.X).
This is a procedural macro for automatically deriving EndianWritableAt, EndianReadableAt, and HasSize traits for structs whose members already implement the above traits.
The following piece of Rust code.
use endian_writer_derive::EndianWritable;
#[derive(EndianWritable)]
#[repr(C)]
struct MyStruct {
a: u32,
b: u16,
c: u8,
}
Expands to:
use endian_writer::*;
#[repr(C)]
struct Simple {
a: u32,
b: u16,
c: u8,
}
impl HasSize for Simple {
const SIZE: usize = <u32 as HasSize>::SIZE + <u16 as HasSize>::SIZE + <u8 as HasSize>::SIZE;
}
impl EndianWritableAt for Simple {
unsafe fn write_at<W: EndianWriter>(&self, writer: &mut W, offset: isize) {
let a = self.a;
writer.write_at(&a, offset);
let b = self.b;
writer.write_at(&b, offset + <u32 as HasSize>::SIZE as isize);
let c = self.c;
writer.write_at(
&c,
offset + <u32 as HasSize>::SIZE as isize + <u16 as HasSize>::SIZE as isize,
);
}
}
impl EndianReadableAt for Simple {
unsafe fn read_at<R: EndianReader>(reader: &mut R, offset: isize) -> Self {
let a = <u32 as EndianReadableAt>::read_at(reader, offset);
let b =
<u16 as EndianReadableAt>::read_at(reader, offset + <u32 as HasSize>::SIZE as isize);
let c = <u8 as EndianReadableAt>::read_at(
reader,
offset + <u32 as HasSize>::SIZE as isize + <u16 as HasSize>::SIZE as isize,
);
Self { a, b, c }
}
}
This code is equivalent to what a human would write, in terms of functionality, at no overhead.
Fields are written to the output in the order they are declared in the source code.
Consider the following struct
#[derive(EndianWritable)]
struct WeirdOrder {
c: u8,
b: u16,
a: u32,
}
The struct will be written in the order of u8
, u16
and lastly u32
.
On the other hand, Rust may rearrange the fields as u32
, u16
and lastly u8
.
In other words, the derive macro treats the code as if the struct is #[repr(C, packed(1))]
.
If padding is desired, the user must manually create it in the struct.
For information on how to work with this codebase, see README-DEV.MD.
Licensed under MIT.
Learn more about Reloaded's general choice of licensing for projects..