I'm trying to learn the Rust macro system by writing a simple macro that generates a struct based on some unsigned integer type (u8
, u16
, u32
, u64
). I want something like this:
bitmessage! {
struct Header(u16);
version: 8, 5; // the first number is the length, second is value
data: 8, 5;
}
To be more specific, I'm looking for some way to store certain information in an unsigned integer type with various offsets. One use case is to read some bytes and construct some kind of "message":
[ 15 14 13 12 11 10 09 08 | 07 06 05 04 03 02 01 01 ]
The higher part of the message contains some data/information, the lower part a versioning field. (This is just a toy example).
This is my effort so far, but the inner repeating expansion does not compile:
macro_rules! bitmessage {
(struct $name:ident($n:ty);
$($field_name:ident: $length:expr, $value:expr;)*) => {
struct $name ($n);
$($name.1 = $name.1 | $value << $length)*
};
}
One solution could be to store the relevant bytes in a struct, implementing it directly (or with a trait) to get the appropriate fields, but this would involve too much bit-shifting logic (no problem with that, but there must be a more convenient way).
I am aware of bitflags and bitfield. Neither of them matches my use case.