Clasma
A procedural attribute macro to reduce boilerplate when passing partially borrow structs into functions.
Overview
The #[partial] function annotation generates a macro_rules! macro of the same name and does not touch the function signature. This macro is callable similarly to the original function, except that one can pass a struct instance to provide the arguments annotated with #[clasma].
This attempts to make partial or "split" borrows more ergonomic in Rust, where the borrow checker sometimes requires functions to borrow references to individual fields rather than a single mutable reference to the parent struct, leading to verbose call sites.
Usage
let mut x = Mystruct ;
The first argument to foo! is the struct to be partially borrowed. One passes the remaining arguments without #[clasma] attributes in the same order as the signature.
foo!;
// expands to:
// foo(&mut x.a, &x.b, 3);
One can reorder struct fields, as long as field names match up with #[clasma] argument names. One can also optionally provide generic parameters inside angle brackets <...>.
bar!;
// expands to:
// bar::<&str>("hello", &x.b, &mut x.a);
Lifetime parameters are also supported.
const y: Mystruct = Mystruct ;
baz!;
// expands to:
// baz::<'static>(&y.b, &y.a, &3);
Motivating Example
Imagine a Tourist with a list of travel destinations, that counts the number of times he visits one of his destinations.
Before
Without partial borrowing, this code does not compile.
The issue is that visit unnecessarily borrows self.destinations mutably when it only needs an immutable borrow. A workaround would be to borrow each struct field separately on every call to visit:
However, this gets tedious as the number of fields increases.
With clasma::partial
The partial macro handles borrowing and argument passing.
Installation