https://github.com/andogq/assert_layout
Assert struct layouts, including field sizes and offsets.
https://github.com/andogq/assert_layout
assert encoding field-size layout macro memory-layout offset proc-macro rust sizeof static-assertions struct-layout
Last synced: about 1 month ago
JSON representation
Assert struct layouts, including field sizes and offsets.
- Host: GitHub
- URL: https://github.com/andogq/assert_layout
- Owner: andogq
- License: apache-2.0
- Created: 2025-04-03T10:39:21.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2025-04-03T10:42:57.000Z (12 months ago)
- Last Synced: 2025-08-23T18:20:55.715Z (7 months ago)
- Topics: assert, encoding, field-size, layout, macro, memory-layout, offset, proc-macro, rust, sizeof, static-assertions, struct-layout
- Language: Rust
- Homepage: https://crates.io/crates/assert_layout
- Size: 16.6 KB
- Stars: 0
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# assert_layout
***Assert struct layouts, including field sizes and offsets.***
`assert_layout` provides a single proc-macro which will perform compile-time assertions for certain
qualities of a struct. In addition to field size and offset, it's also possible to provide concrete
types for generics and assert that the layout still holds.
## Overview
Struct containers can use the `size` assertion to assert the size of the struct.
```rust
use assert_layout::assert_layout;
#[assert_layout(size = 1)]
#[repr(packed)]
struct MyStruct {
field: u8,
}
```
Similarly, each field can use the `size` and `offset` assertions.
```rust
use assert_layout::assert_layout;
#[assert_layout(size = 5)]
#[repr(packed)]
struct MyStruct {
#[assert_layout(offset = 0, size = 1)]
field: u8,
#[assert_layout(offset = 2, size = 4)]
another_field: f32,
}
```
### Generics
If the struct contains generics, concrete types can be provided for assertions using `generics`.
For instance, the following assertion would expand with `T = u32`.
```rust
use assert_layout::assert_layout;
#[assert_layout(size = 4, generics = "u32")]
#[repr(packed)]
struct MyStruct {
#[assert_layout(offset = 0, size = 4)]
field: T,
}
```
Multiple generic parameters can by provided with commas between them, in addition to consts (in the
same manner as `MyStruct<...>`).
```rust
use assert_layout::assert_layout;
#[assert_layout(size = 64, generics = "8, f64")]
#[repr(packed)]
struct MyStruct {
#[assert_layout(offset = 0, size = 64)]
field: [T; N],
}
```
The `generics` attribute can be provided multiple times in order to assert different combinations
of generics.
```rust
use assert_layout::assert_layout;
#[assert_layout(size = 12, generics = "u32, u64", generics = "i32, i64")]
#[repr(packed)]
struct MyStruct {
#[assert_layout(offset = 0, size = 4)]
field: T,
#[assert_layout(offset = 4, size = 8)]
another_field: U,
}
```
### Namespaces
Sometimes generic combinations will not be compatible with each other, so namespaces can be used to
isolate the assertions. A namespace is created using `namespace(...)`, where `namespace` is a
unique identifier for the namepsace, and the previously described assertions (`generics`, `offset`,
`size`) are within the brackets. Everything within the namespace will be asserted in isolation.
```rust
use assert_layout::assert_layout;
#[assert_layout(little(size = 4, generics = "u32"), big(size = 8, generics = "u64"))]
#[repr(packed)]
struct MyStruct {
#[assert_layout(little(offset = 0, size = 4), big(offset = 0, size = 8))]
field: T,
}
```
If there are common assertions between the namespaces (such as `offset = 0` above), they can be
omitted from the namespace and asserted at the top level.
```rust
use assert_layout::assert_layout;
#[assert_layout(
generics = "u32",
generics = "u64",
little(size = 4, generics = "u32"),
big(size = 8, generics = "u64")
)]
#[repr(packed)]
struct MyStruct {
#[assert_layout(offset = 0, little(size = 4), big(size = 8))]
field: T,
}
```