haxetink / tink_json

Macro powered JSON.
The Unlicense
34 stars 9 forks source link

intermediate typedef #55

Open francescoagati opened 5 years ago

francescoagati commented 5 years ago

hi, in a case like this can be possible have the typedef intermedie generated for the json definition?

enum A {
    A1(b:B);
}

enum B {
    B1(c:C);
}

enum C {
    C1(s:String);
}

typedef X = {
    a:A
}

 class Main {

    static function main() {
        var x:X = {
            a: A1(B1(C1("test")))
        };
        var s = tink.Json.stringify(x);
        trace(s);
        var x2:X = tink.Json.parse(s);
        var rt = switch (x2.a) {
            case A1(B1(C1(s))): s;
        };
        trace(rt);
    }
}
kevinresol commented 5 years ago

What is the issue here?

francescoagati commented 5 years ago

I want generale a schema for the JSON generated.

back2dos commented 5 years ago

Isn't X the schema? Or you mean you want to export X as JSON schema?

francescoagati commented 5 years ago

I wanted to generate a JSON schema. But Can be right also only have a new typedef forse the JSON generated

back2dos commented 5 years ago

I don't understand the second part. Isn't X already the typedef?

francescoagati commented 5 years ago

Imagine this enum

enum Color {
  Rgb(a:Int, b:Int, c:Int);
  Hsv(hsv:{ hue:Float, saturation:Float, value:Float });//notice the single argument with name equal to the constructor
  Hsl(value:{ hue:Float, saturation:Float, lightness:Float });
  White;//no constructor
}

i would like to have this typedef

{ Rgb: { "a": Int, "b": Int, "c": Int}}
{ Hsv: { "hue": Int, "saturation": Int, "value": Int }}
{ Hsl: { "value: { "hue": Int, "saturation": Int, "lightness": Int } }}

in this mode i can generate also the schema for example for typescript or jsonschema

back2dos commented 5 years ago

Ah, ok ... I understand now. Well, this could be interesting, in particular because we now allow the type to vary depending on constructor :D

francescoagati commented 5 years ago

yes, for example using a generic build for generate the intermediate typedef for the json.

francescoagati commented 5 years ago

this can be related https://github.com/HaxeFoundation/haxe/issues/4630

kevinresol commented 5 years ago

@francescoagati your linked issue is probably not related. Because tink_json has its own way to serialize haxe enums which is independent of the enum's runtime representation.

francescoagati commented 5 years ago

@kevinresol yes i know. now i am working on a library for generate typefed compatible with tink_json for the generation of the enum. when i have finish i will publish this on github

kevinresol commented 4 years ago

we now allow the type to vary depending on constructor :D

I have strong belief in TypeScript that it can handle this with something like:

"White" | {"Rgb": {a:number, b:number, c:number}}

But I don't think it worth the trouble creating Haxe typedefs (or is it even possible to create a useful one?)

back2dos commented 4 years ago

Yeah, in Haxe this will probably be super awkward. What might be interesting is the ability to generate json schema, although that will also hit a wall when it comes to custom parsers/serializers and such.

francescoagati commented 4 years ago

for example jhttps://lib.haxe.org/p/json2object/ json2Object has a JsonSchemaWriter for generate a jsonschema but for use it with typescript i need to do two steps for convert the jsonschema in typescript. i would like to use a intermediate typedef because in this mode i can expose this typed in typescript using hxtsdgen

back2dos commented 4 years ago

What's the problem with json-schema-to-typescript?

francescoagati commented 4 years ago

yes is only for haven't a two steps passage

kevinresol commented 3 years ago

So I just tried JSON Schema and I think it is expressive enough to describe tink_json's output.

enum Color {
    White;
    Hsl(value:{ hue:Float, saturation:Float, lightness:Float });
    Hsv(hsv:{ hue:Float, saturation:Float, value:Float });
}

Schema:

{
    "oneOf": [
        { "type": "string", "const": "White" },
        {
            "type": "object",
            "required": ["Hsl"],
            "properties": {
                "Hsl": {
                    "type": "object",
                    "required": ["value"],
                    "properties": {
                        "value": {
                            "type": "object",
                            "required": ["hue", "lightness", "saturation"],
                            "properties": {
                                "hue": {
                                    "type": "number"
                                },
                                "lightness": {
                                    "type": "number"
                                },
                                "saturation": {
                                    "type": "number"
                                }
                            }
                        }
                    }
                }
            }
        },
        {
            "type": "object",
            "required": ["Hsv"],
            "properties": {
                "Hsv": {
                    "type": "object",
                    "required": ["hue", "saturation", "value"],
                    "properties": {
                        "hue": {
                            "type": "number"
                        },
                        "saturation": {
                            "type": "number"
                        },
                        "value": {
                            "type": "number"
                        }
                    }
                }
            }
        }
    ]
}

Examples:

"White"
{"Hsv":{"hue":1,"saturation":2,"value":3}}
{"Hsl":{"value":{"hue":1,"lightness":3,"saturation":2}}}
francescoagati commented 3 years ago

Json2Object support json schema

kevinresol commented 3 years ago

I made a branch with initial support of json schema: https://github.com/haxetink/tink_json/tree/schema

but further work is still needed to support custom rules (@:json/@:jsonStringify/@:jsonParse)