Declarative macro for match contents in String

I'm a beginner. Now I have a demand for converting String to a variable name. I want to use macro to do it.
How can I match the contents in String by using declarative macro?
I tried procedural macro, but it's too complex.

Macros are expanded at compile time while a String's value is only known at runtime, so the only way you might be able to implement this is with something that expands to a chain of if string == "foo" { foo } else if .... You can use the stringify(!) macro to take an ident (i.e. a variable name) and get a string containing that name.

Is this similar to what you had in mind?


macro_rules! variable_by_name {
  ( $value:expr => $( $name:ident )|* ) => {
    match $value.as_str() {
      $( stringify!($name) => $name, )*
      _ => todo!("Handle the error"),
    }
  }
}

fn main() {
    let one = 1;
    let two = 2;
    let three = 3;
    let string = "three".to_string();
    
    let value = variable_by_name!(string => one | two | three);
    println!("{}", value);
}

(playground)

Thanks. The macro is great but now I changed my idea.

At first I decided to convert String to variable name since I stored lambda functions in struct (I'm trying to write a Lisp interpreter) . So it's difficult to use Hashmap to store the structure. Therefore, I had the idea to store struct in a variable and add its name (String) into a vector. Use a macro to convert the string to variable name when needing the data.

But after I posted the question, I viewed a passage about writing a compiler and I had an new idea.

Thanks again.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.