www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - static functions associated with enums

reply "Dan" <dbdavidson yahoo.com> writes:
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;
}
Mar 21 2013
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
Mar 21 2013