| Crates.io | resource-bound |
| lib.rs | resource-bound |
| version | 0.1.3 |
| created_at | 2026-01-11 20:15:38.313759+00 |
| updated_at | 2026-01-21 23:46:06.382334+00 |
| description | Compile-time enforcement of struct size limits and heap allocation constraints |
| homepage | https://github.com/oOp995/resource-bound |
| repository | https://github.com/oOp995/resource-bound |
| max_upload_size | |
| id | 2036365 |
| size | 12,691 |
resource-bound is a procedural macro crate that enforces compile-time resource constraints on Rust structs.
It allows you to:
This crate is intentionally conservative, explicit, and honest about what Rust can and cannot guarantee at compile time.
See the full CHANGELOG.md for details on all updates and fixes.
Add the dependency:
[dependencies]
resource-bound = "0.1.3"
Import the derive macro and StackOnly trait:
use resource_bound::ResourceBound;
use resource_bound::StackOnly;
//or
use resource_bound::*;
// in case of size overflow you will get compile-time error
// -> attempt to compute `0_usize - 1_usize`, which would overflow
#[derive(ResourceBound)]
#[size_limit=32] // 32 Bytes size struct, ,if the size of fields exceeds
// explictly defined value, you will get compile-time error.
struct StackStruct{
// size is exact value returned by std::mem::size_of()
// size is 32 bytes on 64-bit targets, 24 bytes on 32-bit targets
unit:(),
i32value:i32, //signed-integer i8,i16,i32,i64,i128 are StackOnly marked
u32value:u32, //unsigned-integer u8,u16,u32,u64,u128 are StackOnly marked
f32value:f32, //flaots f32,f64 are StackOnly marked
char_value:char,//char is StackOnly marked
bool_value:bool, //bool is StackOnly marked
usize_value:usize
//std::mem::size_of::<StackStruct>() is:
//32 bytes on 64-bit
//24 bytes on 32-bit
//if you try to set #[size_limit] less than the actual
//size depending on your structure ,you will trigger a
//compile-time error
}
On common platforms:
size_of::<StackStruct>() == 32size_of::<StackStruct>() == 24If the actual size exceeds #[size_limit], compilation will fail.
Heap allocation is disallowed by default.
To allow heap usage, you must opt in explicitly:
#[derive(ResourceBound)]
#[size_limit = 48] // in Bytes
#[allow_heap = true] //default is false, if you want heap explicilty opt-in
// #[allow_heap = true] ,
//othetwise #[allow_heap = false] is the default
//lifetimes are allowed for the sake of storing ref
//generics is disable intentionally , because generic heap behaviour
//is not guaranted at compile-time neither at runtime
//actually using generics with ResourceBound will trigger compile-error
struct HeapStruct<'a>{
string_value:String,
str_value:&'a str,
box_value:Box<i32>,
}
This makes heap usage visible and intentional, while still enforcing a maximum struct size.
In embedded, systems, and performance-critical Rust code, it is often necessary to ensure that certain data structures:
Rust itself does not provide a built-in way to enforce these constraints declaratively.
resource-bound fills this gap by providing a derive macro that performs static checks during compilation.
When you write:
#[derive(ResourceBound)]
#[size_limit = 32]
struct MyStruct { /* ... */ }
resource-bound guarantees at compile time that:
std::mem::size_of::<MyStruct>() <= 32All checks are performed at compile time. There is no runtime overhead.
It is important to be explicit about limitations:
Heap usage is approximated by explicit type allow-listing, not by analysis.
If you need runtime memory tracking or allocator instrumentation, this crate is not the right tool.
#[allow_heap] defaults to false
heap-allocating types such as Vec, String, and Box are rejected by default
#[size_limit] enforces a hard upper bound on size_of::<Self>()
#[size_limit] enforced by the compiler, compile-time error if missing.
All violations result in compile-time errors.
By default, the following primitive scalar types are considered stack-only and allowed:
()boolchari8, i16, i32, i64, i128u8, u16, u32, u64, u128isize, usizef32, f64All other types are rejected unless heap usage is explicitly enabled.
Lifetimes are allowed:
struct RefStruct<'a> {
value: &'a u32,
}
Borrowing and lifetimes:
if you are borrowing &T then allocating mechanism is unknown even if T implements resource_bound::StackOnly, so it is must be featured with allow_heap=trueGeneric type parameters are intentionally disallowed:
struct Generic<T> {
value: T,
}
Generic heap behavior cannot be reliably verified at compile time, so ResourceBound rejects generic structs by design.
When a constraint is violated, resource-bound emits clear, targeted compile-time errors that:
No runtime panics. No silent failures.
resource-bound follows a few core principles:
If a property cannot be proven at compile time, it is not assumed.
This crate is intentionally strict in its release v 0.1.3.
Future versions may:
Breaking changes will follow semantic versioning.
Licensed under the MIT license.
resource-bound is designed for developers who care deeply about predictability, clarity, and compile-time guarantees.
If that matches your use case, this crate was built for you.