How to use a colon and other symbols inside macroRules?

I have the following macro:

macro_rules! hash {
  ( $( $key:expr: $val:expr ),* ) => {
    {
      let mut hash_map = std::collections::HashMap::new();

      $(
        hash_map.insert($key, $val);
      )*

      hash_map
    }
  };
}

I want to use it to create a hash map like that: let map = hash!{"Mike": 19, "Anna": 20}. When I try to compile the code, it doesn't allow my to use a ":". The error message says that I cannot use a colon "after expr fragments". The error is the second line in the macro when using a colon after $key:expr. Anyone has any idea how I can fix that?

This is due to inherent syntactic ambiguity, so you'll have to choose another symbol. A usual choice is =>. Or you can use a crate like maplit.

2 Likes

So are you 100% sure that there is no way around that? Then I'll leave it open for about a day in case someone that knows something that we don't can help and then I'll close it. Thanks a lot for you time!

Also I have to point out that I found a way to do it here but this won't work in my case cause I want to use $( macroRules ),* and it doesn't seem to work there

Yes. The only valid symbols after an expr matcher are =>, ,, and ;. You can also require the expression to be enclosed in brackets, and anything can follow the closing bracket.

2 Likes

Thanks a lot, have a nice day

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.