8000 Merge pull request #161 from haxiomic/haxiomic-community-posts · HaxeFoundation/code-cookbook@d07b969 · GitHub
[go: up one dir, main page]

Skip to content

Commit d07b969

Browse files
authored
Merge pull request #161 from haxiomic/haxiomic-community-posts
Add strictly typed JSON macro article
2 parents a20c975 + 7206b5e commit d07b969

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed
71.8 KB
Loading
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
[tags]: / "macro,json,expression-macro,configuration"
2+
3+
# Strictly Typed JSON
4+
5+
It's possible read JSON files at compile time into strictly typed objects in Haxe.
6+
7+
<img src="assets/haxe-json-macro.png" />
8+
9+
Normally you might load a JSON file with something like this:
10+
```haxe
11+
var json = haxe.Json.parse(sys.io.File.getContent(path));
12+
```
13+
14+
Instead, if you load the JSON in a macro, then the JSON data will be available at compile time and therefore the types will be known:
15+
16+
Create a file called **JsonMacro.hx** (or whatever you like) and add this:
17+
```haxe
18+
macro function load(path:String) {
19+
return try {
20+
var json = haxe.Json.parse(sys.io.File.getContent(path));
21+
macro $v{json};
22+
} catch (e) {
23+
haxe.macro.Context.error('Failed to load json: $e', haxe.macro.Context.currentPos());
24+
}
25+
}
26+
```
27+
28+
Then use this to load your JSON instead:
29+
30+
```haxe
31+
var leveldata = JsonMacro.load('leveldata.json');
32+
33+
for (i in leveldata.array) { // works now because we know the type of the leveldata object
34+
}
35+
```
36+
37+
**Explanation**: We run the original `Json.parse(File.getContent())` snippet in a macro function so it will execute when Haxe compiles our calls to `JsonMacro.load()`. Instead of returning the JSON object, in macros we need to return _syntax_. So we must convert our JSON object into Haxe syntax – just as if we'd typed our JSON out manually as Haxe objects. Fortunately there's a built-in operator for converting values into Haxe syntax, it's the ['macro-reification-value-operator': `$v{ some-basic-value }`](https://haxe.org/manual/macro-reification-expression.html). We could also use [`Context.makeExpr(value, position)`](https://api.haxe.org/haxe/macro/Context.html#makeExpr) to do the same job. We wrap the JSON reading in a `try-catch` so we can tidy-up error reporting a little.
38+
39+
With this approach, the JSON's content is embedded into your compiled program and _not_ loaded at runtime, therefore, the path argument must be a constant string and cannot be an expression evaluated at runtime.
40+
41+
> Author: [George Corney](https://github.com/haxiomic)

0 commit comments

Comments
 (0)
0