October 18, 2012 Re: Code review: JSON unmarshaller | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tyler Jameson Little | On 2012-10-17 19:39, Tyler Jameson Little wrote: > I could make my marshaller/unmarshaller only update objects in place. I > think this is more useful and would remove the overlap between orange > and the JSON library. We could then write a JSON archiver for orange and > include it in std.json as well. > > The call to unmarshal would look like: > > bool unmarshalJSON(T)(JSONValue val, out T ret); Orange works with the archive at a lower level. For example, the archive doesn't really have to know how to (un)archive an object or struct. The serializer will break down the object into its fields and ask the archive to (un)archive the individual fields. The only thing the archive needs to know is that "here starts an object, from now on all (un)archived values will be part of the object until I say otherwise". > The following restrictions would apply: > > * T must be fully instantiated (all pointers are valid [not null]) That seems to be an unnecessary restriction. > * T must not be recursive (results in infinite recursion, and hence > stack overflow) I think the serializer in Orange can handle this. That would mean the archive doesn't need to handle this. > And the marshaller: > > JSONValue marshalJSON(T)(in T val); > > For marshalling, the restrictions are: > > * Slices are handled as if they were an array (copy all values) So mean: int[] a = [3, 4, 5, 6]; int[] b = [1 .. $ - 1]; That "a" and "b" would be marshaled as two distinct arrays? In Orange, I think the serializer will handle this and the archive doesn't need to care. I tried to but as much of the code in the serializer so the archives doesn't need to bother with these kind of things. > * Same as unmarshaller, except null pointers will be treated as JSON null If you can marshal a null pointer, how can you not unmarshal it? > I really like Go's JSON marshaller/unmarshaller, so I'm trying to model > after that one. It allows updating an object in place, which was already > a goal. > > There should probably be some standard D serialization format. In > working with a structure trained on data (for machine learning, natural > language processing, etc), a complete serialization solution makes > sense. But for simple data passing, JSON makes a lot of sense. Absolutely, there is a need for both, see below. > What do you think, do you think there's a place in Phobos for a simple > JSON marshaller/unmarshaller? Absolutely. I think there is a need for several types and variants of serialization. Sometimes you need to have a fully capable serialization library that can handle all types, custom serialization of third party types and so on. In other cases you don't really care an just want to dump some data to disk or whatever. > I'll have some updated code soon, and I'll post back when that's done, > in case you'd like to have a look. -- /Jacob Carlborg |
October 18, 2012 Re: Code review: JSON unmarshaller | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tyler Jameson Little | On 2012-10-17 21:44, Tyler Jameson Little wrote: > Here's the updated code. It's got a marshaller and unmarshaller: > > https://gist.github.com/3894337 > > It's about 650 lines. If you have time, I'd be very interested in > getting some feedback (or from anyone else who sees this post of course). > > The main problem I'm having right now is that classes/structs have to be > static. I'm not 100% sure why the compiler cannot see non-static > classes/structs at compile time. Do you happen to know why? It seems > like a template should work in either case, assuming I'm understanding D > templates correctly. What do you mean with "static structs/classes"? Are you talking about nested classes and structs? > I didn't find any clear documentation for static outer classes, only > static inner classes. It's not the same as static Java classes, which > cannot be instantiated (if memory serves). -- /Jacob Carlborg |
October 18, 2012 Re: Code review: JSON unmarshaller | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tyler Jameson Little | On 2012-10-17 20:36, Tyler Jameson Little wrote: > The mentioned solution doesn't account for shared fields from a super > class: > > class A { int a; } > class S { int b; } > > foreach (i, type; typeof(S.tupleof)) { > enum name = S.tupleof[i].stringof[4..$]; > writef("(%s) %s\n", type.stringof, name); > } > > This will print: > > (int) b Just do something like this: alias BaseTypeOf!(S) BaseType; BaseType t = type; And run the same loop again. -- /Jacob Carlborg |
October 18, 2012 Re: Code review: JSON unmarshaller | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tyler Jameson Little | On 2012-10-17 21:44, Tyler Jameson Little wrote: > Here's the updated code. It's got a marshaller and unmarshaller: > > https://gist.github.com/3894337 > > It's about 650 lines. If you have time, I'd be very interested in > getting some feedback (or from anyone else who sees this post of course). I'll try and see if I can find some time to give feedback on this. -- /Jacob Carlborg |
October 18, 2012 Re: Code review: JSON unmarshaller | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On 2012-10-17 22:03, Kagamin wrote: > Can it serialize Variant? No, but I'm working on it. Actually, it can serialize it, but not deserialize it. -- /Jacob Carlborg |
October 18, 2012 Re: Code review: JSON unmarshaller | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tyler Jameson Little | On Monday, 15 October 2012 at 20:35:34 UTC, Tyler Jameson Little wrote:
> I'm basically trying to reproduce other JSON marshallers, like Go's, but using compile-time reflection. Go uses runtime reflection, which D notably does not support. I like the idea of compile-time reflection better anyway. There are a few things that would make it easier (like a __traits call like allMembers that excludes functions).
>
> I use a lot of JSON, so a JSON marshaller/unmarshaller is going to save a lot of time, and make my code a lot cleaner.
>
I like Go's JSON convenience as well. There is a nice feature where you can add attributes to the members that are then available at runtime and therefore used by the serializer. So you could have:
------
type AcquiredRetired struct {
Acquired tvm.Date `bson:"a"`
Retired tvm.Date `bson:"r"`
}
------
Here it specifies a shortened key for bson, but you can do the same for json. The size benefit can be significant. A design choice they made is to only serialize members that are capitalized which means visible.
There is a nice json serialize/deserialize library in vibed.
When I throw this struct at your marshalJSON I get compile errors.
----------
import std.stdio;
struct X {
class D {
string b = "B";
}
string a = "A";
D d;
}
void main() {
auto c = new X();
auto o = marshalJSON(c);
writeln(o);
}
----------
Thanks
Dan
|
Copyright © 1999-2021 by the D Language Foundation