Hey! Thank you very much for feedback. I've applied most of the suggested changes. As for the lfun::create() approach to object deserializing - I've been thinking about it, but it's troublesome for some edge cases, like arrays and tuples.
czw., 17 sty 2019 o 18:56 Henrik Grubbström (Lysator) @ Pike (-) developers forum 10353@lyskom.lysator.liu.se napisał(a):
Hi.
I came to the point where I spent so much time on providing Pike support for QuickType, that I'd probably manage to manually write DAP and LSP
pmods
by now. So I've decided to stop there and deliver it as-is. Despite the generated code's likely poor performance, it's been thoroughly tested and proven to work for most test cases both for JSON, and JSON Schema.
I really, really wanted to reuse Standards.JSON API, or else I would wind up rewriting the whole JSON serialization module. That's why I ended up calling JSON.encode, which invokes the encoded object's encode_json
method,
inside JSON.decode. It's necessary because Pike member names are not necessary JSON's keys. For exmaple, 'else' is a perfectly valid key name
in
JSON, while it's a reserved keyword in many programming languages. QuickType has it's ways to handle such situations. Another known blunder is that it tends to append member declarations with 'mixed' when rendering from JSON Schemas. It's likely related to how QuickType handles Schema's optional properties. Here you can play around with it: https://app.quicktype.io/#l=pike
Hmm... From the JSON example:
| #define TO_MIXED(x) Standards.JSON.decode(Standards.JSON.encode(x))
Why do the above? Under normal circumstances it should be a (slow) no-op (at least when it is called from encode_json()).
[...] | string encode_json() { | mapping(string:mixed) json = ([]); | | json["greeting"] = TO_MIXED(greeting); | json["instructions"] = TO_MIXED(instructions);
More efficient would be to create the mapping inline:
string encode_json() { mapping(string:mixed) json = ([ "greeting": TO_MIXED(greeting), "instructions": TO_MIXED(instructions), ]);
[...] | Welcome Welcome_from_JSON(mixed json) {
Why is json declared mixed above?
| Welcome retval = Welcome(); | | retval.greeting = json["greeting"]; | retval.instructions = json["instructions"]; | | return retval; | }
I'd prefer having an lfun::create() in the Welcome class, that knows how to initialize from the mapping.
protected void create(mapping(string:mixed)|void json) { if (!json) return; greeting = json["greeting"]; instructions = json["instructions"]; }
... Welcome Welcome_from_JSON(mapping(string:mixed) json) { return Welcome(json); }
/grubba