D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 7821 - std.conv.to is broken for enums
Summary: std.conv.to is broken for enums
Status: RESOLVED DUPLICATE of issue 4744
Alias: None
Product: D
Classification: Unclassified
Component: phobos (show other issues)
Version: D2
Hardware: All All
: P2 major
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-04-04 11:29 UTC by Andrej Mitrovic
Modified: 2012-04-04 17:39 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Andrej Mitrovic 2012-04-04 11:29:28 UTC
import std.conv;

enum Tag
{
     A
    ,AB
}

void main()
{
    Tag tag1 = to!Tag("A");   // ok
    Tag tag2 = to!Tag("AB");  // fail
}

ConvException: Unexpected 'B' when converting from type string to type Tag

It appears if you have an enum field name that begins with another field's name std.conv.to fails to parse it. This is a blocker for me.
Comment 1 Andrej Mitrovic 2012-04-04 11:31:55 UTC
(In reply to comment #0)
> This is a blocker for me.

OK not a blocker, I can implement a simple template function that converts strings to fields.
Comment 2 Andrej Mitrovic 2012-04-04 11:50:48 UTC
First attempt at a workaround:

import std.stdio;
import std.conv;
import std.string;
import std.traits;
import std.metastrings;

string toSwitch(T)()
{
    typeof(return) result;
    
    string cases;
    foreach (arg; EnumMembers!T)
    {
        cases ~= "case " ~ `"` ~ to!string(arg) ~ `"` ~ ":\n";
        cases ~= Format!("return %s.%s;\n", T.stringof, to!string(arg));
    }
    
    result ~= "
        auto myTo(string input)
        {
            switch(input)
            {
                " ~ cases ~ `
                
                default:
                    throw new Exception(format("Can't convert '%s' to type %s.", input, ` ~ `"` ~ T.stringof ~ `"` ~ `));
            }
        }
    `;

    return result;
}

template myTo(T)
    if (is(T == enum))
{
    mixin(toSwitch!T);
}

enum Tag
{
     A
    ,AB
}

void main()
{
    Tag tag1 = myTo!Tag("A");    // ok
    Tag tag2 = myTo!Tag("AB");   // ok
    Tag tag3 = myTo!Tag("ABC");  // fail, ok
}

Works pretty nicely even though it can be implemented much nicer. Yay D. :)
Comment 3 yebblies 2012-04-04 17:39:37 UTC

*** This issue has been marked as a duplicate of issue 4744 ***