orderless
generates macros for you that allow you to use orderless/named functions in Rust.
```rs
fn add(a: usize, b: usize) -> usize { a + b }
// Compiles to add(2, 2) for no runtime performance hit! add!(b = 2); // 4 ```
impl
).const
and static
variables.a = a
to a
.impl_orderless
for make_orderless
in impl
blocks.Documentation is provided on docs.rs.
call_orderless!
call_orderless!
is the proc macro that does all the heavy lifting. It takes a bunch of info such as the function's name, the order of the arguments, and the default values.
rs
call_orderless! {
func = two,
order(a, b),
defs(a = false, b = false),
args(a = true, b = false),
}
As you can see, using it on its own is pretty pointless. But it's perfect for other macros to pass info they have to it.
create_orderless!
create_orderless!
is another helper macro. It simplifies the process of writing call_orderless!
by generating a macro_rules!
macro which has most of the info built in.
```rs create_orderless! { func = two, order(a, b), defs(a = false, b = false) }
// Generates...
// Note order(...)
disappears because it's integrated into defs(...)
by create_orderless!
.
macrorules! two {
( $($argname:ident $(= $argvalue:expr)?),*$(,)? ) => {
::orderless::callorderless!(
func = two,
defs(a = false, b = false),
args($($argname $(= $argvalue)?),*),
)
};
() => {
::orderless::call_orderless!(
func = two,
defs(a = false, b = false),
args(),
)
};
}
// Called like... two!(b = true); ```
Now you have a function-like macro which can be used very simply.
make_orderless
make_orderless
is an attribute macro which simplifies the process even more by grabbing info already available in the function's definition.
```rs
fn two
// Generates the same thing as create_orderless!
...
```
impl_orderless
The main problem with make_orderless
is that since it generates a macro_rules!
right there, it can't be used inside of impl
blocks.
```rs struct Args {}
impl Args { #[make_orderless(defs(a = false, b = false))] // ERROR!! pub fn two(a: bool, b: bool) -> (bool, bool) { (a, b) } } ```
Fortunately, the impl_orderless
macro makes this possible.
```rs struct Args {}
impl Args { #[make_orderless(defs(a = false, b = false))] // SUCCESS!! pub fn two(a: bool, b: bool) -> (bool, bool) { (a, b) } } ```
It does this by removing all the make_orderless
attributes and converting them into create_orderless!
outside of the impl
block.
With all this chaining it's macro-ception. A macro that converts a macro to another macro, which creates a macro, which calls a macro. But in the end this is all compile-time and doesn't impact runtime performance at all. two!()
simply compiles to two(false, false)
!