Skip to content

Instantly share code, notes, and snippets.

@SpexGuy
Last active March 15, 2024 22:41
Show Gist options
  • Save SpexGuy/8723a4b890331658ebef090be1d2b562 to your computer and use it in GitHub Desktop.
Save SpexGuy/8723a4b890331658ebef090be1d2b562 to your computer and use it in GitHub Desktop.
Zig: Using tagged unions to make a simple json formatter
const JsonString = struct {
value: []const u8,
};
const JsonNumber = struct {
value: f64,
};
const JsonObject = struct {
const Property = struct {
name: []const u8,
value: JsonValue,
};
values: []Property,
};
const JsonArray = struct {
values: []JsonValue,
};
const JsonValue = union(enum) {
String: *JsonString,
Number: *JsonNumber,
Object: *JsonObject,
Array: *JsonArray,
};
fn stringifyWarn(val: JsonValue) void {
const warn = @import("std").debug.warn;
switch (val) {
.String => |str| warn("\"{}\"", str.value),
.Number => |num| warn("{}", num.value),
.Array => |arr| {
warn("[");
for (arr.values) |arrayVal, i| {
if (i != 0) warn(", ");
stringifyWarn(arrayVal);
}
warn("]");
},
.Object => |obj| {
warn("{{");
for (obj.values) |prop, i| {
if (i != 0) warn(", ");
warn("\"{}\"", prop.name);
warn(":");
stringifyWarn(prop.value);
}
warn("}}");
},
}
}
test "unions" {
const Property = JsonObject.Property;
const tree = JsonValue{
.Object = &JsonObject{
.values = [_]Property{
Property{
.name = "hash",
.value = JsonValue{ .String = &JsonString{ .value = "fa354de12356743f" } },
},
Property{
.name = "expression",
.value = JsonValue{
.Array = &JsonArray{
.values = [_]JsonValue{
JsonValue{ .Number = &JsonNumber{ .value = 42 } },
JsonValue{ .String = &JsonString{ .value = "+" } },
JsonValue{
.Array = &JsonArray{
.values = [_]JsonValue{
JsonValue{ .Number = &JsonNumber{ .value = 7 } },
JsonValue{ .String = &JsonString{ .value = "*" } },
JsonValue{ .Number = &JsonNumber{ .value = 55 } },
},
},
},
JsonValue{ .String = &JsonString{ .value = "-" } },
JsonValue{ .Number = &JsonNumber{ .value = 31.45 } },
},
},
},
},
},
},
};
stringifyWarn(tree);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment