gen_ident_range!() { /* proc-macro */ }
Available on crate feature macro_utils only.
Expand description

Generates identifiers. passing them to a callback macro.

Repetition Syntax

The syntax for describing the generated identifiers:

for <ident> * in <range>

Where <ident> is any valid identifier.

Where <range> can be either <number> .. <number> or <number> ..= <number>.

Where <number> can be any of:

  • An integer literal

  • count(....): Which counts the amount of token trees in (....). Macro parameters (eg: $foo) are one token tree, and matched pairs of []/()/{} count as one token tree regardless of the tokens inside.

Version compatibility

This macro requires Rust 1.45.0 to be invoked inside of a function.

Example

Basic

Basic examples of using this macro, and what it passes to a callback macro.

For a more realistic example you can look at the one below

use core_extensions::gen_ident_range;
 
fn main() {
    assert_eq!(hello(), "world");
    assert_eq!(foo(), "bar");
}
 
// Calls the `expected_0_to_2` macro.
gen_ident_range!{
    crate::expected_0_to_2!{hello "world"}
    for stuff_* in 0..3
}
 
// Calls the `expected_1_to_4` macro.
gen_ident_range!{
    crate::expected_1_to_4!{foo "bar" baz}
    // `count(....)` here counts 4 token trees
    for pre_* in 1..=count(a (b c) [d e f] {g h i j})
}

#[macro_export]
macro_rules! expected_0_to_2{
    ($func:ident $lit:literal  (stuff_0 stuff_1 stuff_2)) => {
        fn $func() -> &'static str {
            $lit
        }
    }
}
 
#[macro_export]
macro_rules! expected_1_to_4{
    ($func:ident $lit:literal baz  (pre_1 pre_2 pre_3 pre_4)) => {
        fn $func() -> &'static str {
            $lit
        }
    }
}

More Realistic Example

use core_extensions::gen_ident_range;
 
fn main() {
    assert_eq!(add_unsigned(3, 5, 8), 16);
    assert_eq!(add_signed(-3, 8), 5);
 
}
 
adder_fn!{ pub fn add_unsigned(u16, u32, u64) -> u64 }
adder_fn!{ fn add_signed(i8, i16) -> i64 }
 
 
 
#[macro_export]
macro_rules! adder_fn {
    ($vis:vis fn $func:ident ($($arg_ty:ty),* $(,)?) -> $ret_ty:ty) => {
        gen_ident_range!{
            $crate::__priv_adder_fn!{
                ($vis fn $func ($($arg_ty,)*) -> $ret_ty)
            }
            for arg_* in 0..count($($arg_ty)*)
        }
    }
}
 
#[macro_export]
macro_rules! __priv_adder_fn {
    (
        ($vis:vis fn $func:ident ($($arg_ty:ty,)*) -> $ret_ty:ty)
        ($($arg:ident)*)
    ) => {
        $vis fn $func($($arg: $arg_ty,)*) -> $ret_ty {
            // assuming that Default::default is zero or empty
            <$ret_ty as $crate::__::Default>::default()
            $(
                + <$ret_ty as $crate::__::From<_>>::from($arg)
            )*
        }
    }
}
 
 
#[doc(hidden)]
pub mod __ {
    pub use core_extensions::gen_ident_range;
     
    pub use std::convert::From;
    pub use std::default::Default;
}