#std.Io.Reader JSON parsing
1 messages · Page 1 of 1 (latest)
looks like std.json.parseFromTokenSource using a std.json.Reader that you initialize with the reader
reader is std.json.Reader.init(allocator, io_reader)
That's one example of how I did it in one of my projects.
const file = try dev_maps_dir.openFile(m.name, .{});
var file_reader = file.reader(&.{});
var json_str = std.io.Writer.Allocating.init(allocator);
defer json_str.deinit();
_ = try std.Io.Reader.streamRemaining(&file_reader.interface, &json_str.writer);
const parsed = try std.json.parseFromSlice(
std.json.Value,
allocator,
json_str.written(),
.{}
);
i would also use parseFromTokenSource instead of parseFromSlice if you want to parse from a file. that skips allocating and reading the whole file into a string.
here's a passing test using that approach
const std = @import("std");
const S = struct { a: u8, b: u8 };
test {
const f = try std.fs.cwd().openFile("/tmp/tmp.json", .{});
defer f.close();
const t_gpa = std.testing.allocator;
var rbuf: [256]u8 = undefined;
var fr = f.reader(&rbuf);
var json_r = std.json.Reader.init(t_gpa, &fr.interface);
defer json_r.deinit();
const s = try std.json.parseFromTokenSource(S, t_gpa, &json_r, .{});
defer s.deinit();
try std.testing.expectEqual(1, s.value.a);
try std.testing.expectEqual(2, s.value.b);
}
works in 0.15
/tmp/tmp.json
{ "a": 1, "b": 2 }