www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Usage of custom class with JSONValue

reply Andre <andre s-e-a-p.de> writes:
Hi,

I have a class which has already an alias this to a string array,
so I can use it in a foreach loop.

class MyClass
{
	string[] _data;
	alias _data this;
	// ...
}

void main()
{
	import std.json;
	auto jsValue = JSONValue(new MyClass());
}

For some generic code I need an implicit conversion of MyClass so 
I can
use it for a JSONValue. For the coding above I receive a compiler 
error:
static assert  "unable to convert type "MyClass" to json"

Is there anything I can do?

Kind regards
André
Mar 24 2016
parent reply Edwin van Leeuwen <edder tkwsping.nl> writes:
On Thursday, 24 March 2016 at 08:15:12 UTC, Andre wrote:
 Hi,

 I have a class which has already an alias this to a string 
 array,
 so I can use it in a foreach loop.

 class MyClass
 {
 	string[] _data;
 	alias _data this;
 	// ...
 }

 void main()
 {
 	import std.json;
 	auto jsValue = JSONValue(new MyClass());
 }

 For some generic code I need an implicit conversion of MyClass 
 so I can
 use it for a JSONValue. For the coding above I receive a 
 compiler error:
 static assert  "unable to convert type "MyClass" to json"
JSONValue only works with the build in types, not with user defined types. Either you define a specific function for the class that returns a JSONValue. Easiest way to do that would be to build an associative array with strings as keys with the names, and JSONValues as values and turn that into JSONValue, i.e. (untested): class MyClass { string[] _data; alias _data this; // ... JSONValue toJSON() { JSONValue[string] aa; JSONValue[] dataJSON = _data.map!((a) => JSONValue(a)).array; aa["data"] = JSONValue(dataJSON); return JSONValue(aa); } } Alternatively there are multiple serialization libraries that will allow you to turn any user defined type from and to JSONValues. https://code.dlang.org/packages/painlessjson https://code.dlang.org/packages/jsonizer Cheers, Edwin
Mar 24 2016
next sibling parent Rene Zwanenburg <renezwanenburg gmail.com> writes:
On Thursday, 24 March 2016 at 08:24:46 UTC, Edwin van Leeuwen 
wrote:
 Alternatively there are multiple serialization libraries that 
 will allow you to turn any user defined type from and to 
 JSONValues.

 https://code.dlang.org/packages/painlessjson
 https://code.dlang.org/packages/jsonizer

 Cheers, Edwin
I don't know the above libraries so I can't comment on their quality, but I've used vibe.d's json module extensively and it's pretty solid. Vibe has also recently been split up into multiple subpackages, so you only have to depend on vibe-d:data and don't have to pull in the rest.
Mar 24 2016
prev sibling parent reply arturg <var.spool.mail700 gmail.com> writes:
On Thursday, 24 March 2016 at 08:24:46 UTC, Edwin van Leeuwen 
wrote:
 JSONValue only works with the build in types, not with user 
 defined types. Either you define a specific function for the 
 class that returns a JSONValue. Easiest way to do that would be 
 to build an associative array with strings as keys with the 
 names, and JSONValues as values and turn that into JSONValue, 
 i.e. (untested):
 class MyClass
 {
 	string[] _data;
 	alias _data this;
 	// ...
    JSONValue toJSON()
   {
     JSONValue[string] aa;
     JSONValue[] dataJSON = _data.map!((a) => 
 JSONValue(a)).array;
     aa["data"] = JSONValue(dataJSON);
     return JSONValue(aa);
   }
 }
isnt alias this supposed to do this implicitly? convert this auto jsValue = JSONValue(new MyClass()); into this auto jsValue = JSONValue((new MyClass())._data);
Mar 24 2016
parent reply Edwin van Leeuwen <edder tkwsping.nl> writes:
On Thursday, 24 March 2016 at 11:39:13 UTC, arturg wrote:
 isnt alias this supposed to do this implicitly?

 convert this
 auto jsValue = JSONValue(new MyClass());

 into this
 auto jsValue = JSONValue((new MyClass())._data);
Good point, I did not catch that. That indeed should work and seems to be a bug. Does it work if _data is a base type (string or int, etc..)
Mar 24 2016
parent reply Andre <andre s-e-a-p.de> writes:
On Thursday, 24 March 2016 at 16:03:13 UTC, Edwin van Leeuwen 
wrote:
 On Thursday, 24 March 2016 at 11:39:13 UTC, arturg wrote:
 isnt alias this supposed to do this implicitly?

 convert this
 auto jsValue = JSONValue(new MyClass());

 into this
 auto jsValue = JSONValue((new MyClass())._data);
Good point, I did not catch that. That indeed should work and seems to be a bug. Does it work if _data is a base type (string or int, etc..)
Thanks for the answers. I also wonder why alias this does not the job. Unfortunatelly even if it works, the _data is not the data I want to be used as value for JSONValue. _data only contains keys, the values are stored in another variable. JSONValue should contain both. I hoped there is some operator overloading for implicit conversion of my class to JSONValue. I solved the issue with an toJSON method and a generic functionality which checks for this method. Kind regards André
Mar 24 2016
parent Uldis <uldis.kalninsh gmail.com> writes:
On Thursday, 24 March 2016 at 17:03:25 UTC, Andre wrote:
 I hoped there is some operator overloading for implicit 
 conversion of my
 class to JSONValue.
 I solved the issue with an toJSON method and a generic 
 functionality which
 checks for this method.

 Kind regards
 André
Vibe.d has some serialization with toJson(), fromJson() methods: http://vibed.org/api/vibe.data.json/serializeToJson Maybe you can work with that?
Mar 24 2016