0
votes

How can enum be used with std.json.JSONValue in D? The implementing code does not have access to the module types and to! cannot be used, that's the reason for the CommonType!(OriginalType!()) call.

import std.json;
import std.stdio;
import std.traits;

enum Kind : string
{
    dog = "Dog",
    cat = "Cat",
    pony = "Pony"
};

unittest
{
    writeln("TEST: std.json.JSONValue for enum");

    Kind animal = Kind.dog;
    Kind[] pets = [Kind.cat, Kind.dog];

    static if (is(typeof(animal) == enum))
    {
        writeln("enum");
    }

    //JSONValue a = JSONValue(animal);  // <-- Assertion failed: (0), function unqualify, file mtype.c, line 2022.
    JSONValue a = JSONValue(cast(CommonType!(OriginalType!(typeof(animal))))animal);  // <--  this is OK

    static if (is(typeof(pets) == enum))
    {
        writeln("array of enum");
    }

    //JSONValue p = JSONValue(pets);  // <-- Assertion failed: (0), function unqualify, file mtype.c, line 2022.
    //JSONValue p = JSONValue(???);
}
1

1 Answers

0
votes

You can use convert your enum values to strings and back using std.conv.to.

import std.json;
import std.conv : to;
import std.algorithm : map, equal;
...

Kind animal = Kind.dog;
Kind[] pets = [Kind.cat, Kind.dog];

// convert Kind to string and store in JSONValue
JSONValue json1 = animal.to!string;
// extract string from JSONValue convert to Kind
assert(animal == json1.str.to!Kind); 

JSONValue json2 = pets.to!(string[]);
// map JSONValues to strings, then Kinds
auto pets2 = json2.array.map!(x => x.str.to!Kind);
assert(pets2.equal(pets));

Using string, the JSON values would be represented as strings matching the enum names. You could instead use int or anything else that can be converted to both your enum type and a JSONValue.