Skip to content

Instantly share code, notes, and snippets.

@nadako
Last active October 31, 2020 03:34
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save nadako/6503134 to your computer and use it in GitHub Desktop.
Save nadako/6503134 to your computer and use it in GitHub Desktop.
JSON-schema type builder prototype.
{
"type": "object",
"required": ["intProp", "boolProp"],
"properties": {
"intProp": {"type": "integer"},
"numProp": {"type": "number"},
"strProp": {"type": "string"},
"boolProp": {"type": "boolean"},
"arrayProp": {
"type": "array",
"items": {
"type": "object",
"properties": {
"dynObj": {"type": "object"},
"dynArr": {"type": "array"}
}
}
}
}
}
#if macro
import haxe.macro.Context;
import haxe.macro.Expr;
class SchemaTypeBuilder
{
public static function build(ref:String):haxe.macro.Type
{
var schema = haxe.Json.parse(sys.io.File.getContent(ref));
var type:ComplexType = parseType(schema);
return haxe.macro.ComplexTypeTools.toType(type);
}
static function parseType(schema:Dynamic):ComplexType
{
return switch (schema.type)
{
case "integer":
return macro : Int;
case "number":
return macro : Float;
case "string":
return macro : String;
case "boolean":
return macro : Bool;
case "array":
parseArrayType(schema);
case "object":
parseObjectType(schema);
case unknown:
throw "Unsupported JSON-schema type: " + unknown;
};
}
static function parseArrayType(schema:Dynamic):ComplexType
{
var type = if (Reflect.hasField(schema, "items"))
parseType(schema.items);
else
macro : Dynamic;
return macro : Array<$type>;
}
static function parseObjectType(schema:Dynamic):ComplexType
{
if (Reflect.hasField(schema, "properties"))
{
var required:Array<String> = Reflect.hasField(schema, "required") ? schema.required : [];
var fields:Array<Field> = [];
var props = schema.properties;
for (field in Reflect.fields(props))
{
var meta = [];
if (!Lambda.has(required, field))
meta.push({name: ":optional", params: [], pos: Context.currentPos()});
var subschema = Reflect.field(props, field);
fields.push({
name: field,
pos: Context.currentPos(),
kind: FVar(parseType(subschema)),
meta: meta
});
}
return TAnonymous(fields);
}
return macro : Dynamic<Dynamic>;
}
}
#end
class Sample
{
static function main()
{
var a:MyType = {
intProp: 10,
boolProp: true
};
}
}
typedef MyType = haxe.macro.MacroType<[SchemaTypeBuilder.build("mytype.json")]>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment