#std.Io.Reader JSON parsing

1 messages · Page 1 of 1 (latest)

vocal pulsar
#

How do I parse JSON from a file using the new std.Io.Reader interface?

buoyant grove
tepid saddle
#

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(),
    .{}
);
lapis sky
#

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 }