isamert
isamert

Reputation: 492

How do I create a constant enum variant with heap-allocated data to use in pattern matching?

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?

Upvotes: 0

Views: 903

Answers (1)

Shepmaster
Shepmaster

Reputation: 430671

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:

Upvotes: 3

Related Questions