Skip to content

Instantly share code, notes, and snippets.

@AustinEast
Created April 13, 2021 15:25
Show Gist options
  • Save AustinEast/71e97a7c8c574dd2a31e75614ad19c3f to your computer and use it in GitHub Desktop.
Save AustinEast/71e97a7c8c574dd2a31e75614ad19c3f to your computer and use it in GitHub Desktop.
Haxe Macro for defining simple data Classes from an Array of Strings
import haxe.macro.Context;
using StringTools;
class Macros {
static final node_package = 'nodes';
static final node_prefix = 'Node';
static function title_case(str:String) {
return str.length < 1 ? str.toUpperCase() : str.charAt(0).toUpperCase() + str.substr(1).toLowerCase();
}
/**
* Generates and instantiates a Class built from the supplied Array of Strings. All fields are set to type of `String`.
**/
public static macro function create(field_names:Array<String>) {
var node_name = node_prefix;
for (field in field_names)
node_name += title_case(field);
try {
Context.getType('$node_package.$node_name');
} catch (e) {
var node_class = macro class {
public function new() {}
}
node_class.name = node_name;
node_class.pack = [node_package];
var pos = Context.currentPos();
for (field in field_names)
node_class.fields.push({
pos: pos,
name: field,
kind: FVar(macro:String),
access: [APublic]
});
Context.defineType(node_class);
}
return macro Type.createInstance($p{[node_package, node_name]}, []);
}
}
class Test {
static function main() {
// Create a class
var a = Macro.create(['name', 'surname']);
a.name = 'haxe';
a.surname = 'lover';
trace(a.name);
// Test creating class of same type
var b = Macro.create(['name', 'surname']);
b.name = 'haxe';
b.surname = 'lover';
trace(b.surname);
// Test creating class of a different type
var c = Macro.create(['favorite_fruit', 'favorite_animal']);
c.favorite_fruit = 'banana';
c.favorite_animal = 'monke';
trace(c.favorite_animal);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment