Created
July 21, 2015 14:42
-
-
Save nadako/086124686083ce122b28 to your computer and use it in GitHub Desktop.
Type-safe localization.
This file contains 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.Context; | |
import haxe.macro.Expr; | |
import haxe.macro.Type; | |
using haxe.macro.Tools; | |
class LocaleMacro { | |
static function build():Array<Field> { | |
var fields = Context.getBuildFields(); | |
var newFields:Array<Field> = []; | |
for (field in fields) { | |
switch (field.kind) { | |
case FVar(t, null): | |
field.kind = FProp("get", "never", t); | |
newFields.push({ | |
pos: field.pos, | |
name: "get_" + field.name, | |
access: [APrivate, AStatic, AInline], | |
kind: FFun({ | |
ret: macro : String, | |
args: [], | |
expr: macro return LocaleStorage.localize($v{field.name}, null) | |
}) | |
}); | |
case FFun(fun): | |
var args = []; | |
for (arg in fun.args) | |
args.push(macro $v{arg.name} => $i{arg.name}); | |
field.kind = FFun({ | |
ret: fun.ret, | |
args: fun.args, | |
expr: macro return LocaleStorage.localize($v{field.name}, $a{args}) | |
}); | |
default: | |
throw new Error("Invalid field type. Should be either string var or a function", field.pos); | |
} | |
field.access = [APublic, AStatic]; | |
} | |
return fields.concat(newFields); | |
} | |
} |
This file contains 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
class LocaleStorage { | |
public static var data:Map<String,String>; | |
public static function localize(key:String, args:Map<String,String>):String { | |
var s = data[key]; | |
if (s == null) | |
return 'NOT LOCALIZED: $key'; | |
if (args == null) | |
return s; | |
var r = ~/\{(\w+)\}/; | |
var buf = new StringBuf(); | |
while (true) { | |
if (r.match(s)) { | |
buf.add(r.matchedLeft()); | |
var v = args[r.matched(1)]; | |
if (v == null) | |
v = "NO VALUE"; | |
buf.add(v); | |
s = r.matchedRight(); | |
} else { | |
buf.add(s); | |
break; | |
} | |
} | |
return buf.toString(); | |
} | |
} |
This file contains 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
@:build(LocaleMacro.build()) | |
class Locale { | |
var some_object_name:String; | |
var some_window_title:String; | |
function some_window_message(object_name:String):String; | |
} | |
class Main { | |
static function main() { | |
LocaleStorage.data = [ | |
"some_object_name" => "ъжсло", | |
"some_window_title" => "пепяка", | |
"some_window_message" => "погладь {object_name}, сука!", | |
]; | |
trace(Locale.some_window_title); | |
trace(Locale.some_window_message(Locale.some_object_name)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment