Re: std.json dynamic initialization of JSONValue

2011-12-07 Thread David

Am 06.12.2011 22:30, schrieb Kai Meyer:

I posted this on D.learn, but got no responses. I'm hoping it's because
I'm asking the wrong crowd.

I'm finding std.json extremely well written, with one glaring exception.

I can't seem to figure out how to do this:

JSONValue root = JSONValue(null, JSON_TYPE.OBJECT);
root.object["first_object"] = JSONValue(null, JSON_TYPE.OBJECT);
root.object["first_string"] = JSONValue("first_string", JSON_TYPE.STRING);

which would decode to:

{"first_object":{},"first_string":"first_string"}

What I end up having to do is:
JSONValue root;
root.type = JSON_TYPE.OBJECT;
root.object["first_object"] = JSONValue();
root.object["first_object"].type = JSON_TYPE.OBJECT;
root.object["first_string"] = JSON_Value();
root.object["first_string"].type = JSON_TYPE.STRING;
root.object["first_string"].str = "first_string";

That just feels like I'm doing it wrong. Is there a way to dynamically
initialize a JSONValue struct? If I try to intialize the JSONValue
object with anything other than simply null, or empty string, I either
get a compile error or a segfault at run-time.

root.object["first_object"] = JSONValue(null, JSON_TYPE.OBJECT);

compile error:
Error: overlapping initialization for integer

root.object["first_string"] = JSONValue("first_string");
run-time segfault.

Any ideas?
That's the reason why I use libdjson (well the bug with dmd 2.053 made 
me switch, but I didn't switch back): 
https://256.makerslocal.org/wiki/Libdjson


Re: std.json dynamic initialization of JSONValue

2011-12-06 Thread Adam D. Ruppe
Robert Jacques;

I like your modules a lot. I'm sure it will be a bit of a pain to integrate
it into my existing codebase, but they look like it'd be worth it!


Re: std.json dynamic initialization of JSONValue

2011-12-06 Thread Robert Jacques

On Tue, 06 Dec 2011 19:15:26 -0500, Jonathan M Davis  
wrote:

On Tuesday, December 06, 2011 18:26:39 Adam D. Ruppe wrote:

Kai Meyer Wrote:
> I like it. Any reason something like this doesn't already exist in
> std.json?
I think it's just that nobody has done updates to std.json for a while, but
I don't really know.


I believe that Robert Jacques has a revised version of std.json that he
intends to put up for review, but it relies on changes that he's made to
std.variant which also need be reviewed.

- Jonathan M Davis


Correct. Andrei suggested that since JSONValue is a tagged union, it should 
really use std.Variant.Algebraic as its representation, which necessitated 
fixing both Variant and Algebraic so that was possible. The code and 
documentation links are below if you'd like to try it out/comment on it. The 
only thing unintuitive in my revision from your use case is creating an empty 
JSON object or array:

JSON.Value myObject = JSON.Value[string].init;
JSON.Value myArray  = JSON.Value[].init;

Since this is undocumented :( I think I'm going to add some aliases 
(JSON.Object_init, JSON.Array_init) to simplify things for people.

https://jshare.johnshopkins.edu/rjacque2/public_html/json2.mht
https://jshare.johnshopkins.edu/rjacque2/public_html/variant.mht

https://jshare.johnshopkins.edu/rjacque2/public_html/json2.d
https://jshare.johnshopkins.edu/rjacque2/public_html/variant.d


Re: std.json dynamic initialization of JSONValue

2011-12-06 Thread Jonathan M Davis
On Tuesday, December 06, 2011 18:26:39 Adam D. Ruppe wrote:
> Kai Meyer Wrote:
> > I like it. Any reason something like this doesn't already exist in
> > std.json?
> I think it's just that nobody has done updates to std.json for a while, but
> I don't really know.

I believe that Robert Jacques has a revised version of std.json that he 
intends to put up for review, but it relies on changes that he's made to 
std.variant which also need be reviewed.

- Jonathan M Davis


Re: std.json dynamic initialization of JSONValue

2011-12-06 Thread Adam D. Ruppe
Kai Meyer Wrote:
> I like it. Any reason something like this doesn't already exist in std.json?

I think it's just that nobody has done updates to std.json for a while, but
I don't really know.


Re: std.json dynamic initialization of JSONValue

2011-12-06 Thread Kai Meyer

On 12/06/2011 02:42 PM, Adam D. Ruppe wrote:

I could swear I replied in the other group... must have gotten lost in the
series of tubes.

Anyway, I think std.json is easiest to use with a little template wrapper 
instead
of making JSONValues directly.

Try this on for size:

=

import std.json;
import std.conv;
import std.traits;

JSONValue toJsonValue(T)(T a) {
JSONValue val;
static if(is(T == typeof(null))) {
val.type = JSON_TYPE.NULL;
} else static if(is(T == JSONValue)) {
val = a;
} else static if(isIntegral!(T)) {
val.type = JSON_TYPE.INTEGER;
val.integer = to!long(a);
} else static if(isFloatingPoint!(T)) {
val.type = JSON_TYPE.FLOAT;
val.floating = to!real(a);
} else static if(is(T == bool)) {
if(a == true)
val.type = JSON_TYPE.TRUE;
if(a == false)
val.type = JSON_TYPE.FALSE;
} else static if(isSomeString!(T)) {
val.type = JSON_TYPE.STRING;
val.str = to!string(a);
} else static if(isAssociativeArray!(T)) {
val.type = JSON_TYPE.OBJECT;
foreach(k, v; a) {
val.object[to!string(k)] = toJsonValue(v);
}
} else static if(isArray!(T)) {
val.type = JSON_TYPE.ARRAY;
val.array.length = a.length;
foreach(i, v; a) {
val.array[i] = toJsonValue(v);
}
} else static if(is(T == struct)) { // also can do all members of a 
struct...
val.type = JSON_TYPE.OBJECT;

foreach(i, member; a.tupleof) {
string name = a.tupleof[i].stringof[2..$];
static if(a.tupleof[i].stringof[2] != '_')
val.object[name] = toJsonValue!(typeof(member), 
R)(member, formatToStringAs, api);
}
} else { /* our catch all is to just do strings */
val.type = JSON_TYPE.STRING;
val.str = to!string(a);
}

return val;
}

string toJson(T)(T a) {
auto v = toJsonValue(a);
return toJSON(&v);
}

/* usage example */
import std.stdio;
void main() {
writeln(toJson(["message": "Hello, world!"]));
}
==


Then, you can either use toJsonValue() to fill in an object similar
to what you were doing before, or use toJson() to skip right
to having a string from a struct, an associative array, or many
other D types.


I like it. Any reason something like this doesn't already exist in std.json?

-Kai Meyer


Re: std.json dynamic initialization of JSONValue

2011-12-06 Thread Adam D. Ruppe
Adam D. Ruppe Wrote:
>   val.object[name] = toJsonValue!(typeof(member), 
> R)(member, formatToStringAs, api);


Whoops, that should have been

val.object[name] = toJsonValue(member);


(I copy pasted this out of my web.d module, which can add a toString() method 
to the json too,
so it's a little more complicated. And probably useless.)


Re: std.json dynamic initialization of JSONValue

2011-12-06 Thread Adam D. Ruppe
I could swear I replied in the other group... must have gotten lost in the
series of tubes.

Anyway, I think std.json is easiest to use with a little template wrapper 
instead
of making JSONValues directly.

Try this on for size:

=

import std.json;
import std.conv;
import std.traits;

JSONValue toJsonValue(T)(T a) {
JSONValue val;
static if(is(T == typeof(null))) {
val.type = JSON_TYPE.NULL;
} else static if(is(T == JSONValue)) {
val = a;
} else static if(isIntegral!(T)) {
val.type = JSON_TYPE.INTEGER;
val.integer = to!long(a);
} else static if(isFloatingPoint!(T)) {
val.type = JSON_TYPE.FLOAT;
val.floating = to!real(a);
} else static if(is(T == bool)) {
if(a == true)
val.type = JSON_TYPE.TRUE;
if(a == false)
val.type = JSON_TYPE.FALSE;
} else static if(isSomeString!(T)) {
val.type = JSON_TYPE.STRING;
val.str = to!string(a);
} else static if(isAssociativeArray!(T)) {
val.type = JSON_TYPE.OBJECT;
foreach(k, v; a) {
val.object[to!string(k)] = toJsonValue(v);
}
} else static if(isArray!(T)) {
val.type = JSON_TYPE.ARRAY;
val.array.length = a.length;
foreach(i, v; a) {
val.array[i] = toJsonValue(v);
}
} else static if(is(T == struct)) { // also can do all members of a 
struct...
val.type = JSON_TYPE.OBJECT;

foreach(i, member; a.tupleof) {
string name = a.tupleof[i].stringof[2..$];
static if(a.tupleof[i].stringof[2] != '_')
val.object[name] = toJsonValue!(typeof(member), 
R)(member, formatToStringAs, api);
}
} else { /* our catch all is to just do strings */
val.type = JSON_TYPE.STRING;
val.str = to!string(a);
}

return val;
}

string toJson(T)(T a) {
auto v = toJsonValue(a);
return toJSON(&v);
}

/* usage example */
import std.stdio;
void main() {
writeln(toJson(["message": "Hello, world!"]));
}
==


Then, you can either use toJsonValue() to fill in an object similar
to what you were doing before, or use toJson() to skip right
to having a string from a struct, an associative array, or many
other D types.


std.json dynamic initialization of JSONValue

2011-12-06 Thread Kai Meyer
I posted this on D.learn, but got no responses. I'm hoping it's because 
I'm asking the wrong crowd.


I'm finding std.json extremely well written, with one glaring exception.

I can't seem to figure out how to do this:

JSONValue root = JSONValue(null, JSON_TYPE.OBJECT);
root.object["first_object"] = JSONValue(null, JSON_TYPE.OBJECT);
root.object["first_string"] = JSONValue("first_string", JSON_TYPE.STRING);

which would decode to:

{"first_object":{},"first_string":"first_string"}

What I end up having to do is:
JSONValue root;
root.type = JSON_TYPE.OBJECT;
root.object["first_object"] = JSONValue();
root.object["first_object"].type = JSON_TYPE.OBJECT;
root.object["first_string"] = JSON_Value();
root.object["first_string"].type = JSON_TYPE.STRING;
root.object["first_string"].str = "first_string";

That just feels like I'm doing it wrong. Is there a way to dynamically 
initialize a JSONValue struct? If I try to intialize the JSONValue 
object with anything other than simply null, or empty string, I either 
get a compile error or a segfault at run-time.


root.object["first_object"] = JSONValue(null, JSON_TYPE.OBJECT);

compile error:
Error: overlapping initialization for integer

root.object["first_string"] = JSONValue("first_string");
run-time segfault.

Any ideas?