On 08/05/2017 05:33 PM, Matthew Remmel wrote:
I feel like I'm missing something, but there has to be an easier way to convert a value into an enum than switching over every possible value: i.e

enum Capitals {
     Indiana = "Indianapolis",
     Illinois = "Chicago",
     Ohio = "Columbus"
}

Capitals enumFromValue(string s) {
     switch (s) {
         case Capitals.Indiana:
             return Capitals.Indiana;
          case Capitals.Illinois:
             return Capitals.Illinois;
          case Capitals.Ohio:
             return Capitals.Ohio;
          default:
throw new Exception(format("No Capitals enum member with value %s", s));
     }
}

int main() {
     Capitals c = enumFromValue("Chicago"); // works

     // I tried using std.conv, but it matches on the enum member name
     c = to!Capitals("Chicago") // fails, no member named Chicago
}

With how redundant the enumFromValue(string) implementation is, I would think there would be an easier way to do it. I'm sure you could use a mixin, a template, or std.traits. I was hoping there was a more 'builtin' way to do it though. Something along the simplicity of:

int main() {
     Capitals c = Capitals("Chicago");
}

Any ideas?

As far as I know, there's no built-in way to do this. But you can simplify and generalize your `enumFromValue`:

----
enum Capitals
{
    Indiana = "Indianapolis",
    Illinois = "Chicago",
    Ohio = "Columbus"
}

E enumFromValue(E)(string s)
{
    import std.format: format;
    import std.traits: EnumMembers;
    switch (s)
    {
        foreach (c; EnumMembers!E)
        {
            case c: return c;
        }
        default:
        immutable string msgfmt = "enum %s has no member with value %s";
        throw new Exception(format(msgfmt, E.stringof, s));
    }
}

void main()
{
    auto c = enumFromValue!Capitals("Chicago");
    assert(c == Capitals.Illinois);
}
----

Reply via email to