orderless!
orderless generates macros for you that allow you to use orderless/named functions in Rust.
// Compiles to add(2, 2) for no runtime performance hit!
add!; // 4
Features
- Attribute macro.
- Procedural macro.
- Paths to functions (functions from crates and
impl). - Default argument values.
- Identifiers.
- Expressions.
-
constandstaticvariables. - Optionally don't provide a default value.
- Shortcut identical name and value to just the name.
a = atoa. - Attribute macro
impl_orderlessformake_orderlessinimplblocks.
Docs
Documentation is provided on docs.rs.
How does it work?
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.
call_orderless!
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.
create_orderless!
// Generates...
// Note `order(...)` disappears because it's integrated into `defs(...)` by `create_orderless!`.
;
=> ;
}
// Called like...
two!;
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.
// 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.
Fortunately, the impl_orderless macro makes this possible.
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)!