www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - setting fields of object using traits

reply Ram_B <zvolkzrus gmail.com> writes:
I'm trying to set fields of object from JSON with traits library. 
How i can to it properly?

import std.stdio;
import std.json;
import std.traits;
import std.meta:  Alias;

class Obj{
	void fromJSON(this T)(JSONValue j){
		foreach(field; FieldNameTuple!T){
			alias member = Alias!(__traits(getMember, T, field));
			static if (__traits(hasMember, member, "fromJSON")){
				member.fromJSON(j[field]);
			} else {
				member = j[field];
			}
		}
	}
}

class A : Obj{
	int a,b;
	C c;
	this(){
		c = new C();
	}
	
}

class C : Obj{
	int a;
	this(){
		a = 0;
	};
}

int main(string[] argv)
{
	string s = "{\"a\": 1, \"b\": 2, \"c\": {\"a\": 3} }";
	JSONValue j = parseJSON(s);
	A a = new A();
	a.fromJSON(j);
	writeln(a.b);
	readln();
     return 0;
}

main.d(14): Error: need 'this' for 'a' of type 'int'
main.d(14): Error: need 'this' for 'b' of type 'int'
main.d(12): Error: template main.Obj.fromJSON cannot deduce 
function from argument types !(c)(JSONValue), candidates are:
main.d(8):        main.Obj.fromJSON(this T)(JSONValue j)
main.d(41): Error: template instance main.Obj.fromJSON!(A) error 
instantiating
Sep 20 2016
parent Jacob Carlborg <doob me.com> writes:
On 2016-09-20 21:45, Ram_B wrote:
 I'm trying to set fields of object from JSON with traits library. How i
 can to it properly?

 import std.stdio;
 import std.json;
 import std.traits;
 import std.meta:  Alias;

 class Obj{
     void fromJSON(this T)(JSONValue j){
         foreach(field; FieldNameTuple!T){
             alias member = Alias!(__traits(getMember, T, field));
             static if (__traits(hasMember, member, "fromJSON")){
                 member.fromJSON(j[field]);
             } else {
                 member = j[field];
I'm pretty sure this won't work. You need to use "this.tupleof[index] = value" to set a value. You can iterate all fields using "T.tupleof" and then get the name of a field using "__traits(identifier, T.tupleof[index]);". Or you can use a string mixin. -- /Jacob Carlborg
Sep 20 2016