On Wed, 15 Dec 2010 09:38:16 -0500, Adam D. Ruppe <destructiona...@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?

Reply via email to