Created
November 14, 2019 23:20
-
-
Save jdonaldson/9d05386b6ff1f559b3f2c365f77a2ac8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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