Skip to content

Instantly share code, notes, and snippets.

@danielo515
Forked from kLabz/Job.hx
Created December 11, 2022 10:53
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 danielo515/38c30b46b70d94d2d22060dc8429c9bb to your computer and use it in GitHub Desktop.
Save danielo515/38c30b46b70d94d2d22060dc8429c9bb to your computer and use it in GitHub Desktop.
Lua test
#if macro
import haxe.macro.Context;
import haxe.macro.Expr;
import haxe.macro.TypeTools;
#end
@:remove // Doesn't seem to work on lua, eh
interface Job<TJobOpt:{}> {}
@:pure
extern function checkOpts<T:{}, TJob:Job<T>>(job:Class<TJob>, opts:T):Void;
macro function make(type:Expr, args:Expr):Expr {
var fieldExprs = switch (args.expr) {
case EObjectDecl(fields):
[for (f in fields) f.field => f.expr];
case _:
throw "Must be called with an anonymous object";
};
switch (Context.typeof(args)) {
case TAnonymous(_.get().fields => fields):
var objFields:Array<ObjectField> = [
for (f in fields) {
switch (f.type) {
case TInst(_.toString() => "Array", [TInst(_.toString() => "String", [])]):
{field: f.name, expr: macro lua.Table.create(${fieldExprs.get(f.name)})};
case _:
{field: f.name, expr: macro ${fieldExprs.get(f.name)}};
}
}
];
var obj = {expr: EObjectDecl(objFields), pos: args.pos};
return macro @:mergeBlock {
// Type checking; should be removed by dce
@:pos(args.pos) Job.checkOpts($type, $args);
// Actual table creation
untyped __lua__("{0}:new({1})", $type, lua.Table.create(null, $obj));
};
case _:
throw "Must be called with an anonymous object";
}
}
typedef Job1_opts = {
final command:String;
final cwd:Null<String>;
final arguments:Array<String>;
}
extern class MyJob1 implements Job<Job1_opts> {}
typedef Job2_opts = {
final command:String;
final cwd:Null<String>;
final arguments:Array<String>;
}
extern class MyJob2 implements Job<Job2_opts> {}
function main() {
var job = Job.make(MyJob1, {
command: "chezmoi",
cwd: "/Users/danielo/",
arguments: ['-v']
});
// local job = MyJob1:new(({arguments = ({"-v"}), command = "chezmoi", cwd = "/Users/danielo/"}));
var job = Job.make(MyJob2, {
command: "chezmoi",
cwd: "/Users/danielo/",
arguments: ['-v']
});
// local job = MyJob2:new(({arguments = ({"-v"}), command = "chezmoi", cwd = "/Users/danielo/"}));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment