[Issue 9821] New: Smarter conversion of strings to enums

d-bugmail at puremagic.com d-bugmail at puremagic.com
Tue Mar 26 13:01:25 PDT 2013


http://d.puremagic.com/issues/show_bug.cgi?id=9821

           Summary: Smarter conversion of strings to enums
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody at puremagic.com
        ReportedBy: jared at economicmodeling.com


--- Comment #0 from Jared Miller <jared at economicmodeling.com> 2013-03-26 13:01:24 PDT ---
Currently std.conv.to requires a string to be the *member name* of an enum in
order to convert it. However, a standard use case when sharing data is to
serialize enum variables using the underlying type of the enum, since different
programs should not be expected to use the same enum naming scheme internally.
The std.conv.to template currently cannot handle such a conversion (from string
version of underlying type to the enum type). This also requires a workaround
going the other direction (i.e., converting enum values to strings). In order
to serialize data in a portable manner, you shouldn't emit enum values as the
string representation of the symbols used in the source code.

This is a significant annoyance that surfaces in std.csv.csvReader, which
requires all data going into an enum to be serialized as the enum member name,
not the string representation of its underlying type.

Example and my current workaround:

-------------
import std.algorithm, std.conv, std.stdio, std.string, std.traits;

enum MyEnum {
    Foo = 1,
    Baz = 7
}

void main()
{
    writeln( to!MyEnum(7) );              // ok.
    writeln( to!MyEnum("Baz") );          // ok.
    try {
        writeln( to!MyEnum("7") );        // throws
    }
    catch(ConvException  e) {
        writeln( e.msg );
    }

    writeln( strToEnum!MyEnum("7") );     // ok.
    writeln( strToEnum!MyEnum("Baz") );   // ok.
}

/*
 * Current workaround for a smarter conversion.
 */
E strToEnum(E, S)(S str)
    if(is(E == enum) && isSomeString!S)
{
    if(countUntil([__traits(allMembers,E)], str) > -1)
        return to!E(str);
    else {
        auto underlyingValue = to!(OriginalType!E)(str);
        if(countUntil([EnumMembers!E], underlyingValue) > -1)
            return cast(E)(underlyingValue);
        else
            throw new ConvException(format(
                    "Value '%s' cannot be converted to enum %s",
                    underlyingValue, E.stringof));            
    }
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list