March 21, 2013
I have an enum, say:

enum AssetCategory {
  Investment,
  PrimaryResidence,
  FamilyProperty,
  FinancialInstrument
}

and I have functions that convert to/from strings to be used in Json (via vibe json). The vibe wants to call out to user supplied toJson/fromJson if both functions are provided and the test for it is:

Json serializeToJson(T)(T value) {
...
 static if( __traits(compiles, value = T.fromJson(value.toJson())) ){
   return value.toJson();
...
}

I would like to use this feature to have the json output the string instead of numeric value (while still retaining numeric value in data structures). The toJson/fromJson functions below are close. They allow for this:

if( __traits(compiles, t.fromJson(t.toJson()) ))

to be true - but that is not the same thing. Is there a trickery to associate a static function with an enum? (e.g. AssetCategory.fromJson(json)) )

Thanks
Dan
-----------

static void fromJson(ref AssetCategory assetType, Json src) {
  string value = cast(string)src;
  writeln("value is ",value);
  final switch(value) {
  case "Investment": { assetType = AssetCategory.Investment; break; }
  case "PrimaryResidence": { assetType = AssetCategory.PrimaryResidence; break; }
  case "FamilyProperty": { assetType = AssetCategory.FamilyProperty; break; }
  case "FinancialInstrument": { assetType = AssetCategory.FinancialInstrument; break; }
  }
}

static Json toJson(AssetCategory assetType) {
  auto result = Json();
  result = text(assetType);
  return result;
}
March 21, 2013
On 03/21/2013 01:34 PM, Dan wrote:

> Json serializeToJson(T)(T value) {
> ...
> static if( __traits(compiles, value = T.fromJson(value.toJson())) ){

It looks like fromJson must be a static member function because the condition is written in a way that fromJson is called on the type itself. (I don't know any trick to bind that to a regular function.)

It may not be suitable in your case but wrapping the enum inside a struct is a solution (struct AssetCategory below):

import std.stdio;
import std.conv;

struct Json
{
    string s;

    this(string s) {
        writefln("constructing with %s", s);
        this.s = s;
    }

    T opCast(T : string)() const
    {
        return s;
    }
}

Json serializeToJson(T)(T value) {
    static if( __traits(compiles, value = T.fromJson(value.toJson())) )
    {
        return value.toJson();

    } else {
        return Json("NOT GOOD: DEFAULT BEHAVIOR");
    }
}

enum AssetCategoryType {
  Investment,
  PrimaryResidence,
  FamilyProperty,
  FinancialInstrument
}

struct AssetCategory
{
    AssetCategoryType assetType;

    alias assetType this;

    static AssetCategory fromJson(Json src) {
        string value = cast(string)src;
        return AssetCategory(value.to!AssetCategoryType);
    }
}

static Json toJson(AssetCategory assetType) {
  auto result = Json();
  result = Json(text(assetType));
  return result;
}

void main()
{
    auto category = AssetCategory(AssetCategoryType.FamilyProperty);
    auto json = serializeToJson(category);
    writeln(json);

    // Test fromJson
    assert(AssetCategory.fromJson(Json("PrimaryResidence")) ==
           AssetCategory(AssetCategoryType.PrimaryResidence));
}

Ali