Skip to content

Instantly share code, notes, and snippets.

@jdonaldson
Created November 14, 2019 23:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdonaldson/9d05386b6ff1f559b3f2c365f77a2ac8 to your computer and use it in GitHub Desktop.
Save jdonaldson/9d05386b6ff1f559b3f2c365f77a2ac8 to your computer and use it in GitHub Desktop.
import haxe.macro.Expr;
import haxe.macro.Context;
class Paths {
public static macro function toPath(value) {
var en = switch Context.follow(Context.typeof(value)) {
case TEnum(_.get() => en, _): en;
case _: throw new Error("not an enum", value.pos);
}
var cases = new Array<Case>();
for (ctorName in en.names) {
var field = en.constructs[ctorName];
var ctorIdent = macro $i{ctorName};
var urlParts = [];
var path_override = field.meta.has("path") ? {
var k = field.meta.extract("path")[0];
var path_expr = k.params[0].expr;
var path = switch(path_expr){
case EConst(CString(str)) : {
str;
}
case _ : {
urlParts = [macro $v{ctorName}];
null;
}
}
path;
} : null;
switch field.type {
case TEnum(_):
cases.push({
values: [ctorIdent],
expr: macro $v{ctorName}
});
case TFun(args, _):
var capturedNames = [];
for (arg in args) {
switch Context.followWithAbstracts(arg.t){
case TInst(ct,[]) : {
var argIdent = macro $i{arg.name};
capturedNames.push(argIdent);
if (path_override == null){
urlParts.push(macro $v{arg.name});
} else {
urlParts.push(macro $v{path_override});
}
}
case TEnum(enm, []) :{
var argIdent = macro $i{arg.name};
capturedNames.push(argIdent);
if (path_override == null){
urlParts.push(macro Paths.toPath($argIdent));
} else {
urlParts.push(macro $v{path_override});
}
}
case _ : {
}
}
}
cases.push({
values: [macro $ctorIdent($a{capturedNames})],
expr: macro $a{urlParts}.join("/")
});
case _:
throw "assert";
}
}
return {
pos: Context.currentPos(),
expr: ESwitch(value, cases, null)
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment