Crates.io | mident |
lib.rs | mident |
version | |
source | src |
created_at | 2025-04-13 17:15:22.793958+00 |
updated_at | 2025-04-13 17:15:22.793958+00 |
description | Macro Identifier toolbox -- generate/concat idents in macros |
homepage | |
repository | https://github.com/ArcaneNibble/mident |
max_upload_size | |
id | 1632003 |
Cargo.toml error: | TOML parse error at line 17, column 1 | 17 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
This crate is a collection of small tools for constructing identifiers inside macro_rules!
declarative macros. This can help reduce unnecessary use of the syn
and quote
crates.
This crate was originally inspired by a combination of the gensym
and paste
crates.
However, unlike gensym
it does not use syn
nor quote
, and it is dumber than paste
.
This crate instead implements a very basic expression evaluator which can combine commands.
Inside the macro body, #
is used to identify a mident
command. Commands output
either an identifier or a stream of tokens. Those which output an identifier can be combined
or nested, but those which output a token stream cannot.
The following commands output an identifier:
#rand
-- will be replaced by __{uuid_v4_simple}
#upcase ident
-- converts ASCII letters to uppercase#downcase ident
-- converts ASCII letters to lowercase#concat(ident_1, ident_2, ...)
-- concatenates identifiers only#flatten(path)
-- converts a type path into an identifier, replacing non-alphanumeric symbols with _{HEX}_
#flatten_basename(path)
-- same as #flatten
, but strips everything before the last :
(thus extracting only the type name)The following commands output a token stream:
#ty_path(path)
-- removes everything after the last :
(thus returning the path to a type but not the type itself).
Returns an empty token stream if there is no :
in the input.This crate only has visibility into tokens and does not have any information about types.
It cannot tell whether two types would be considered equivalent or coerce-able.
When using the #flatten
command in multiple places, the output will only be an exact match
if they are spelled exactly the same (e.g. no type aliases or even differing qualified paths).
// Common macro which creates a variable
macro_rules! gen_ident_ {
($ty:path, $e:expr, $i:ident) => {
const $i: $ty = $e;
};
}
// Create a random identifier
macro_rules! rand_ident {
($ty:path, $e:expr) => {
mident::mident!{ gen_ident_!{$ty, $e, #rand} }
};
}
rand_ident!(u32, 123);
rand_ident!(u32, 123);
// Convert to lowercase
macro_rules! downcase_ident {
($a:ident, $ty:path, $e:expr) => {
mident::mident!{ gen_ident_!{$ty, $e, #downcase $a } }
};
}
downcase_ident!(FoO, u32, 123);
// The variable was created as `foo`
const baz: u32 = foo;
// Concatenate several pieces, while also using multiple mident operations
macro_rules! concat_ident {
($a:ident, $b:ident, $ty:path, $e:expr) => {
mident::mident!{ gen_ident_!{$ty, $e, #concat($a $b _ #upcase #concat($b $a)) } }
};
}
concat_ident!(foo, bar, u32, 123);
const qux: u32 = foobar_BARFOO;
// Example of using `flatten`
macro_rules! flatten_ident {
($a:path, $ty:path, $e:expr) => {
mident::mident!{ gen_ident_!{$ty, $e, #flatten_basename($a) } }
};
}
flatten_ident!(::some::long::path::to::FooStruct<'static, u32, 5, 'a'>, u32, 123);
const uwu: u32 = FooStruct_3C__27_static_2C_u32_2C_5_2C__27_a_27__3E_;
// Example of using `ty_path`
macro_rules! ty_path_test {
($a:path, $e:expr) => {
mident::mident!{
const #rand: #ty_path($a) Vec<u32> = $e;
}
};
}
ty_path_test!(::std::vec::this<'is, 'all, 'ignored, 'static, u32, (owo, uwu)>, Vec::new());