Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible for a macro to turn an identifier lowercase? [duplicate]

Tags:

macros

rust

Is it possible to generate a symbol or identifier in a Rust macro from a string? Or to perform string-like operations on a identifier?

I wanted to generate a method given a symbol, but need to downcase it to obtain the method name.

get!(B);

// should expand to

fn b() -> B {
    // method body
}

It's easy to get close...

macro_rules! get {
    ($kind:ident, $method:ident)
        =>
    {
        fn $method() -> $kind {
           // method body
        }
    }
}

get!(B, b)

But dissatisfying.

like image 627
Phil Lord Avatar asked Sep 05 '18 13:09

Phil Lord


3 Answers

I just wrote a procedural macro (casey) to do this.

#![feature(proc_macro_hygiene)]

use casey::lower;

lower!(B); // would render as `b`

Update

proc_macro_hygiene is stable as of rust 1.45.0, so no longer requires nightly.

like image 89
stacksonstacks Avatar answered Dec 08 '22 08:12

stacksonstacks


The previous answers are all correct; standard declarative macros can't do this, and you can drop to procedural macros instead. However, a simpler alternative to procedural macros (especially if, like myself, that's an area of the language you haven't delved into yet) is dtolnay's paste crate.

An example from those docs:

use paste::paste;

paste! {
    // Defines a const called `QRST`.
    const [<Q R S T>]: &str = "success!";
}

fn main() {
    assert_eq!(
        paste! { [<Q R S T>].len() },
        8,
    );
}

Case conversion is also supported, e.g. [<ld_ $reg:lower _expr>]

like image 22
Bryan Henry Avatar answered Dec 08 '22 09:12

Bryan Henry


No, there isn't a macro that can perform this sort of string manipulation on identifiers.

It is possible to create such a macro in the compiler, but it doesn't seem to be a popular need; today only the experimental concat_idents! comes anything close to this (i.e. string-like operations for identifiers).

Your workaround is currently the only available solution.

like image 28
ljedrz Avatar answered Dec 08 '22 08:12

ljedrz