I’m finding it hard to locate good examples of providing custom jsonParse
functions for objects. I figured that if I’m having issues locating it, then other people probably are too so it’s a good idea to ask. To be clear, I’m not referring to the jsonStringify
.
In the static.zig
file, you can see that there are checks for:
if (std.meta.hasFn(T, "jsonParse")) {
return T.jsonParse(allocator, source, options);
}
Any clear examples of customizing this function that people are aware of?
1 Like
I have found this following tests in static_test.zig
but they’re not particularly explanatory:
const Subnamespaces = struct {
packed_struct: packed struct { a: u32, b: u32 },
union_enum: union(enum) { i: i32, s: []const u8, v },
inferred_enum: enum { a, b },
explicit_enum: enum(u8) { a = 0, b = 1 },
custom_struct: struct {
pub fn jsonParse(allocator: Allocator, source: anytype, options: ParseOptions) !@This() {
_ = allocator;
_ = options;
try source.skipValue();
return @This(){};
}
pub fn jsonParseFromValue(allocator: Allocator, source: Value, options: ParseOptions) !@This() {
_ = allocator;
_ = source;
_ = options;
return @This(){};
}
},
custom_union: union(enum) {
i: i32,
s: []const u8,
pub fn jsonParse(allocator: Allocator, source: anytype, options: ParseOptions) !@This() {
_ = allocator;
_ = options;
try source.skipValue();
return @This(){ .i = 0 };
}
pub fn jsonParseFromValue(allocator: Allocator, source: Value, options: ParseOptions) !@This() {
_ = allocator;
_ = source;
_ = options;
return @This(){ .i = 0 };
}
},
custom_enum: enum {
a,
b,
pub fn jsonParse(allocator: Allocator, source: anytype, options: ParseOptions) !@This() {
_ = allocator;
_ = options;
try source.skipValue();
return .a;
}
pub fn jsonParseFromValue(allocator: Allocator, source: Value, options: ParseOptions) !@This() {
_ = allocator;
_ = source;
_ = options;
return .a;
}
},
};
Briefly, here’s how I made this work with jsonParse
.
The parse is declared as:
pub fn jsonParse(
allocator: std.mem.Allocator,
source: anytype // more on this below
options: std.json.ParseOptions,
) !MyType {
If you’re only trying to be compatible with parseFromSlice
then you can instead declare the source variable as source: *std.json.Scanner
.
From there, the scanner has a next
function that returns tokens. These tokens have information like object begin
which implies that you’ve hit something like a curly bracket.
For the type I needed, I just checked to see that the next
token is a number:
if (token == .number)
Which means it holds onto a sub-slice of the json which contains the numeric string. From there, you just treat that slice like any other by using token.number
.