0

I have this enum:

enum Foo {
    Bar,
    Baz(String),

    // And maybe some other variants    
}

I find myself constantly pattern matching against predefined strings of Baz.

match foo_instance {
    Foo::Baz(ref x) => match x.as_str() {
        "stuff" => ...,
        "anotherstuff" => ...,
    },
    // Other match cases...
}

Sometimes I only match for one case, sometimes 4-5 cases of Foo::Baz. In latter situation, a double match doesn't bother me so much, in fact the grouping makes sense at that point. If I only match against one case of Foo::Baz it doesn't feel right. What I really want to be able to do is this:

const STUFF: Foo = Foo::Baz("stuff".to_string());
const ANOTHER_STUFF: Foo = Foo::Baz("anotherstuff".to_string());

match foo_instance {
    &STUFF => ...,
    &ANOTHER_STUFF => ...,
    // Other match cases...
}

But of course, because of to_string() calls, this won't work (and I also need to derive Eq trait to be able to match against consts which is odd. That may also be a problem for me.). Is there any way to mimic this? For example, using a macro, can I do something like that:

const STUFF: Foo = magic!(Foo::Baz("stuff".to_string());
const ANOTHER_STUFF: Foo = magic!(Foo::Baz("anotherstuff".to_string()));

// Or any other thing that can mimic top level behavior,
// I may create these constants dynamically at program start, that would work too.

match foo_instance {
    another_magic!(STUFF) => ...,
    another_magic!(ANOTHER_STUFF) => ...,
    // Other match cases...
}

Generally speaking, I want to be able to have some constant variants of an enum that contains an heap allocated data (String in this case), so that I can reuse them whenever I need in a match case. What's the best way to deal with this?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
isamert
  • 482
  • 4
  • 12
  • I want to somehow extract all the left hand side of the match case to a constant or something like that. Match guards doesn't help me with that(Yes, it eliminates the need for double match, but its a last resort for me. Maybe I need to edit out the last sentence). Also `map()`ing my enum is not going to work, because it's not a `struct`, I need to match in `map` too. Creating a parallel type seems too weird. I can create a const `static &str` and match against that with those solutions but that would raise another problem. These constants will only have strings and they lack the total meaning. – isamert Jun 18 '18 at 00:04
  • 1
    You've been presented with multiple solutions, but have arbitrarily decided that an answer that does what you need is "too weird"? That's not going to get you very far. Then the answer to your question is: "No". – Shepmaster Jun 18 '18 at 00:06
  • There is only one solution that does what I need along those solutions presented and I found that one too verbose. Pardon my choice of words, I was running out of character limit. The reason is that, I have a lot of `enum`s like this and it will be hard to create parallel types for each of them and apart from that, the solution is just verbose. I would like to hear an answer that is more suitable for my situation, like if I can do that with a macro or something like that. If you say it's impossible that way, then we can mark this question as duplicate. – isamert Jun 18 '18 at 00:19

1 Answers1

3

You cannot create constants with heap-allocated data in current Rust, full stop.

Maybe in the future it will be possible to create a const FOO: String, but there's a lot of work to be done and decisions to be made before that.

using a macro

Macros are not magic. They only let you write certain types of code that you can already write but with a new syntax. Since you cannot create these constants, you cannot write a macro to create them either.


I want to somehow extract all the left hand side of the match case to a constant or something like that. Match guards doesn't help me with that(Yes, it eliminates the need for double match, but its a last resort for me.

Also map()ing my enum is not going to work, because it's not a struct, I need to match in map too.

Creating a parallel type seems too weird.

I can create a const static &str and match against that with those solutions but that would raise another problem. These constants will only have strings and they lack the total meaning.

There is only one solution that does what I need along those solutions presented and I found that one too verbose.

I have a lot of enums like this and it will be hard to create parallel types for each of them and apart from that, the solution is just verbose.

For other readers who can use the alternative solutions which you have already discarded, see also:

For further reading, see also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • I need to clarify that, I am not particularly in a search for constants. As I said in the question(in the comments of last code segment), I can create instances of `enum`s dynamically. I just need to somehow match that dynamically created enum with another instance with a possible help of a macro. Or maybe, even this would work if rust had `#define` like in C : `#define STUFF Foo::Baz(ref x) if x == "stuff"`. Then I could stick that `STUFF` into left hand side of match case. I know rust macros are not expanded into text pre-processing, that's why I asked. – isamert Jun 18 '18 at 00:34