compose-idents
A macro for generating new identifiers (names of variables, functions, traits, etc.) by concatenating one or more arbitrary parts and applying other manipulations.
It was created as an alternative to macro_rules! that doesn't allow creating new identifiers from the macro arguments
and concat_idents! macro from the nightly Rust, which is limited in capabilities and has not been stabilized
since 2015.
Features
-
Identifier generation
Identifiers can be generated via concatenation of multiple parts. Arguments of the outer macro definitions and literals are supported for identifier definitions.
-
Unique identifier generation
Unique identifiers can be deterministically generated by using
hash()function which is uniquely seeded each invocation of the macro. This might be useful for generating unique global variables. -
Functions
Functions can be applied when defining new identifiers for changing case and style.
-
String formatting
Strings can be formatted with
%alias%syntax, which is useful for generating doc-attributes.
Usage
This section contains various usage examples. For even more usage examples look into tests/ directory
of the repository.
Quick start
compose_idents! works by accepting definitions of aliases and a code block where aliases
could be used as normal identifiers. When the macro is expanded, the aliases are replaced with their
definitions:
use compose_idents;
compose_idents!;
Generating tests for different types
Another practical example for how to auto-generate names for macro-generated tests for different data types:
use Add;
use compose_idents;
// Generates tests for u8, u32 and u64 types
generate_add_tests!;
test_add_u8;
test_add_u32;
test_add_u64;
Reference example
This example includes all the features of the macro:
use compose_idents;
compose_idents!;
// It's possible to use arguments of declarative macros as parts of the identifiers.
outer_macro!;
global_var_macro!;
global_var_macro!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Functions
| Function | Description |
|---|---|
upper(arg) |
Converts the arg to upper case. |
lower(arg) |
Converts the arg to lower case. |
snake_case(arg) |
Converts the arg to snake_case. |
camel_case(arg) |
Converts the arg to camelCase. |
pascal_case(arg) |
Converts the arg to PascalCase. |
hash(arg) |
Hashes the arg deterministically within a single macro invocation. |
Alternatives
There some other tools and projects dedicated to identifier manipulation:
- A macro from Nightly Rust that allows to concatenate identifiers. It is limited in functionality and nowhere near to be stabilized: https://doc.rust-lang.org/std/macro.concat_idents.html
- A very similar macro that doesn't support multiple aliases and is not maintained: https://github.com/DzenanJupic/concat-idents
- A macro that allows to define and refer to unique temporary variables: https://crates.io/crates/templest
Development
The following standards are followed to maintain the project: