Skip to content

Instantly share code, notes, and snippets.

@savage69kr
Forked from nadako/SchemaTypeBuilder.hx
Created September 13, 2013 12:11
Show Gist options
  • Save savage69kr/6549876 to your computer and use it in GitHub Desktop.
Save savage69kr/6549876 to your computer and use it in GitHub Desktop.
#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":
TPath({pack: [], name: "Int", params: []});
case "number":
TPath({pack: [], name: "Float", params: []});
case "string":
TPath({pack: [], name: "String", params: []});
case "boolean":
TPath({pack: [], name: "Bool", params: []});
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
TPath({pack: [], name: "Dynamic", params: []});
return TPath({pack: [], name: "Array", params: [TPType(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 TPath({pack: [], name: "Dynamic", params: [TPType(TPath({pack: [], name: "Dynamic", params: []}))]});
}
}
#end
typedef MapItem = haxe.macro.MacroType<[SchemaTypeBuilder.build("schema.json")]>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment