Crate place_macro
source ·Expand description
Place-macro
Macros you wish you had while you were writing your non-proc macro.
This library privides some macros that make writing regural non-proc macros much simpler, readable and with less dirty tricks.
The main macro of this library is place
. It is able to expand the macros
in this library in reverse expansion order.
Every time I’m missing a proc macro while creating macro, I will add it here :).
Macros
place
: expands the following macros in reverse order, see below
ignore
: expands to nothingidentity
: expands to what is given, it bypasses the reverse order in theplace
macrodollar
: expands to dollar sign$
string
: concats the contents into single string, see the docidentifier
: concats the contents into sintle identifier in the same way asstringhead
: expands to the first tokentail
: expands to all but the first tokenstart
: expands to all but the last tokenlast
: expands to the last tokenreverse
: expands to the tokens in reverse orderstringify
: expands to string of the inputreplace_newline
: replaces all newlines and folowing whitespace in literal with the given literalstr_replace
: replace in string literalto_case
: change the case of a identifier
The macro place
Expands the other macros inside in reverse order. The macros inside that
will be expanded are used with a different sintax: instead of calling a
macro as string!("hello" "there")
you call it as
__string__("hello" "there")
. One exception is the macro dollar
that is
called without the parenthesis: __dollar__
instead of __dollar__()
.
For some of the macros there are also shorter names:
__identity__
-__id__
__string__
-__str__
__dollar__
-__s__
__identifier__
-__ident__
__stringify__
-__strfy__
__replace_newline__
-__repnl__
__str_replace__
-__repstr__
The macro to_case
has simplified usage, the case of the macro call will
determine the case to which convert (e.g. __ToCase__(my_ident)
will
expand to MyIdent
). Possible variants:
__TOCASE__
__tocase__
__toCase__
__ToCase__
__to_case__
__TO_CASE__
Example
The following passes:
use place_macro::place;
let res = place!(__string__(1 __string__(2 __identity__(3 __string__(4)))));
assert_eq!(res, "123__string__4");
Why is this useful?
- You can generate identifiers in your macros:
use place_macro::place;
macro_rules! my_cool_macro {
($name:ident -> $t:ty, $body:expr) => {
place! {
fn __identifier__(cool_ $name)() -> $t {
$body
}
}
};
}
my_cool_macro! { foo -> &'static str, "cool!" }
// Expands to:
// ```
// fn cool_foo() -> &'static str {
// "cool!"
// }
// ```
- You can generate strings as macro parameters in your macros:
use place_macro::place;
macro_rules! my_cool_macro {
($name:ident -> $t:ty, $body:expr) => {
place! {
#[doc =
__string__(
"cool function called " $name ". Returns `"
__stringify__($t) "`."
)
]
fn __identifier__(cool_ $name)() -> $t {
$body
}
}
};
}
my_cool_macro! { foo -> &'static str, "cool!" }
// Expands to:
// ```
// #[doc = "cool function called foo. Returns `&'static str`."]
// fn cool_foo() -> &'static str {
// "cool!"
// }
// ```
- Or you can even generate macros in your macros
use place_macro::place;
macro_rules! my_cooler_macro {
($t:ident) => {
place! {
macro_rules! __identifier__(my_ $t _macro) {
(__dollar__ name:ident -> __dollar__ t:ty, __dollar__ body:expr) => {
place! {
#[doc =
__identity__(__string__)(
$t " function called " __dollar__ name ". Returns `"
__identity__(__stringify__)(__dollar__ t) "`."
)
]
fn __identity__(__identifier__)($t __dollar__ name)() -> __dollar__ t {
__dollar__ body
}
}
};
}
}
};
}
my_cooler_macro! { cool };
my_cool_macro! { foo -> &'static str, "cool!" }
// now you have the same function as in the previous example
The last example was a little less readable, but you can see that you can do a lot with this macro.
Links
- Author: BonnyAD9
- GitHub repository: BonnyAD/place_macro
- Package: crates.io
- Documentation: docs.rs
- My Website: bonnyad9.github.io
Macros
- Expands to a single dollar sign, this has no use when it is used alone, but it can be used in the
place
macro - Expans to the first token if present
- Creates a identifier in the same way as the string macro creates string literals.
- Returns exactly the given input
- Ignores all the input, as if there was nothing
- Expands to the last token
- Evaluates the macros in this crate in reverse order
- Replaces newlines and follwing whitespace in string literal with another string.
- Reverses the passed tokens
- Expands to all but the last token
- Replaces in string literal
- Converts the input to string literal, literals are interpreted as their values, punctuation and brackets are ignored and the rest is stringified.
- Should be same to the rust macro stringify
- Expands to all but the first token
- Converts the given identifier to the given case. Second argument is the identifier and the first is string literal representing the target case. The target case can be one of: