JSON (was: emscripten )

Robert Jacques sandford at jhu.edu
Wed Dec 15 09:49:59 PST 2010


On Wed, 15 Dec 2010 09:38:16 -0500, Adam D. Ruppe  
<destructionator at gmail.com> wrote:
> Vladimir Panteleev Wrote:
>> if (resource == "/getfoo")
>> {
>>  struct FooResult { int n; string s; }
>>  return toJSON(FooResult(42, "bar")); // {"n":42,"s":"bar"}
>> }
>
>
> What kind of code did you use there? My app does something
> similar using wrappers of std.json.
>
> JSONValue toJsonValue(T)(T a) {
>         JSONValue val;
>         static if(is(T == JSONValue)) {
>                 val = a;
>         } else static if(__traits(compiles, a.makeJsonValue())) {
>                 val = a.makeJsonValue();
>         } else static if(isIntegral!(T)) {
>                 val.type = JSON_TYPE.INTEGER;
>                 val.integer = to!long(a);
> [......]
>
> And it goes right through a variety of types, including
> structs where it does __traits(allMembers), and ultimately
> settles for to!string if nothing else fits.
>
>
>
> My program also reads json, but I had some trouble with std.json,
> so I had to fork it there. It has a helper function jsonValueToVariant  
> (which just
> became fully usable in dmd 2.050,
> shortening my code a lot, thanks phobos/dmd devs!) which
> pulls it into a std.variant for easy using later.
>
> The trouble I had was std.json.parseJSON claims to be able
> to handle arbitrary input ranges, but when I actually instantiated
> it on plain old string, it refused to compile.
>
> I made it work by switching it to just normal strings in my private
> fork.
>
>
>
>
> What's really cool about these templates is it enables automatic calling  
> of
> functions from the outside. You write a function like:
>
> struct User { ... }
>
> User getUserInfo(int id) { .... }
>
>
> And then this is accessible, through template magic, as:
>
> /app/get-user-info?id=1
>
> Returns a full HTML document with the info
>
> /app/get-user-info?id=1&format=json
>
> Returns the User struct converted to json
>
> /app/get-user-info?id=1&format=xml
>
> The struct as a kind of xml (I didn't spend much time on this so it  
> still sucks)
>
>
> And more. Way cool.
>
>
>
> Anyway, I thought about committing some of my json changes back to  
> std.json, but
> removing the range capability goes against the grain there, and adding  
> the
> templates seems pointless since everyone says std.json is going to be  
> trashed
> anyway. I thought I might have actually been the only one using it!
>
>
> I'm curious what you did in your code. Is it a custom module or did you  
> build off
> the std.json too?

Hi Adam,
I've been working on a replacement for std.json. I posted a preview to the  
phobos list, but I haven't gotten any feedback yet, as its not very high  
priority.

Here is my original post:
I have been working on a re-write of std.json. The purpose was to fix  
implementation bugs, better conform to the spec, provide a lightweight  
tokenizer (Sean) and to use an Algebraic type (Andrei) for JSON values. In  
the progress of doing this, I made my parser 2x faster and updated/fixed a  
bunch of issues with VariantN in order to fully support Algebraic types.  
Both of these libraries are at a solid beta level, so I'd like to get some  
feedback, and provide a patch for those being held back by the problems  
with Algebraic. The code and docs are available at:  
https://jshare.johnshopkins.edu/rjacque2/public_html/. These files were  
written against DMD 2.050 and both depend on some patches currently in  
bugzilla (see the top of each file or below)

Summary of Variant changes:
* Depends on Issue 5155's patch
* VariantN now properly supports types defined using "This".
* Additional template constraints and acceptance of implicit converters in  
opAssign and ctor. i.e. if an Algebraic type supports reals, you can now  
assign an int to it.
* Updated to using opBinary/opBinaryRight/opOpAssign. This adds right  
support to several functions and is now generated via compile time  
reflection + mixins: i.e. Algebraic types of user defined types should  
work, etc.
* Added opIn support, though it currently on works for AAs.
* Added opIndexOpAssign support.
* Added opDispatch as an alternative indexing method. This allows Variants  
of type Variant[string] to behave like prototype structs: i.e. var.x = 5;  
instead of var["x"] = 5;

Notes:
* There's an bugzilla issue requesting opCall support in Variant. While I  
can see the usefulness, syntactically this clashes with the ctor. Should  
this issue be closed or should a method be used as an opCall surrogate?
* Could someone explain to me the meaning/intension of "Future additions  
to Algebraic will allow compile-time checking that all possible types are  
handled by user code, eliminating a large class of errors." Is this  
something akin to final switch support?

Summary of JSON changes:
* Depends on the Variant improvements.
* Depends on Issue 5233's patch
* Depends on Issue 5236's patch
* Issue 5232's patch is also recommended
* The integer type was removed: JSON doesn't differentiate between  
floating and integral numbers. Internally, reals are used and on systems  
with 80-bit support, this encompasses all integral types.
* UTF escape characters are now correctly support.
* All routines/types were encapsulated in a JSON struct for name space  
reasons.
* An Algebraic type is used for JSON values, with  
serialization/de-serialization routines as free methods.
* Serialization/de-serialization centers around a set of input/output  
range to/from token range routines, with separate parser/writer routines.
* Values can be written in either a concise (default) or pretty printed  
format. (i.e. indented with line returns)
* Convenience toString and toStringHR routines exist.
* Simple Type to/from json routines exist, but are marked as to be  
re-evaluated pending std.serialization.
* I've implemented a binary format customized for JSON. Besides preserving  
numeric precision (i.e. 80-bit reals), I found it gave slightly smaller  
file size (~20%) and 2-3x parsing performance for a large numeric dataset  
of mine. I'm not sure if it's worth-while on the whole, so I'd appreciate  
feedback.

Notes:
* Does anyone have a suggestion of a good way to attach methods to an  
Algebraic type? And if we can, should we?


More information about the Digitalmars-d mailing list