akin
Crate for writing repetitive code easier and faster. Check Syntax for information about how to use it.
Why?
I've found myself having to write a lot of repetitive code (mostly when matching against enums in parsing).
The fantastic duplicate had a sort of unintuitive syntax, so I decided to make my own tool.
Example
akin!
Is expanded to:
The good thing about akin is that it detects automatically the number of values of each variable for each scope, so for example "branch" will get copied 4 times (as "num" and "res" both have 4 values), but the main function will only be duplicated once, as all the variables it has have 2 values.
Check the tests/ folder of the repository for more examples.
Syntax
The crate only provides one macro, akin!.
The syntax is as follows:
First, you declare the variables you'll use.
A variable name must start with &, as it's the only way it can differentiate between macro or real declarations.
Also notice that variables end with ;
let &variable = ;
let &variable2 = ;
let &code = ;
Then, when all variables have been declared, you can write the code snippet you want to duplicate.
The amount of times it will be duplicated depends on the variables that are used.
let &lhs = ;
let &rhs = ;
println!;
Will get expanded to:
println!;
println!;
println!;
Because the variables &lhs and &rhs both have 3 values.
As you can see, & is used to declare variables and * is used to "dereference" them to the current value.
If a used variable has less values than another, the last one will be used.
akin!
Expands to
println!;
println!;
All code in variables must be enclosed in brackets {...}.
akin!
Will expand to
if -1 < 0
if 1 < 0
Check the tests/ folder of the repository for more examples.
Raw modifier
By default, akin places a space between all identifiers
let name = 5; // 'name' is an identifier
^^^^
Sometimes, this is not desirable, for example, if trying to interpolate between a function name
let &name = ;
fn _*name...
// Will get wrongly expanded to, because '_' is an identifier
fn _ 1
To avoid it, use the raw # modifier, making the identifier next to the one it affects to not be separated.
let &name = ;
fn #_*name... // *name() is affected by the modifier
// Will get correctly expanded to
This is a limitation on proc_macro parsing, so I doubt it'll be fixed soon.