Can I load a arbitrary json with std.json? Knowledge gaps after highlevel programming

Hi everyone,

I spent a couple of hours trying to read 2 MBs of arbitrary JSON data in Zig and realized that my expectations were off. Seems like I am missing the basic theory.

Long story short I tried to parse a file using the code below without clear understanding of what the first argument T of parseFromSlice was for.

const json = try std.json.parseFromSlice(u8, allocator, raw_json, .{});

Seems like I will need first create the type and then parse the string “into it”. I know the structure of JSON but have only vague idea about how to approach this task. I am also wondering how one would approach processing JSON where the structure is not know or is known only partially.

Am I missing something on a conceptual level when working with low-level languages as opposed to high-level ones? Could you suggest any good reads to fill the gaps?

Thanks!

Hi @Zaurs9000 ,

Take a look at Reading a JSON config in Zig :slight_smile:

1 Like

If I understand the question correctly, you are looking for std.json.Value.jsonParse. std.json.parseFromSlice parses a string as JSON, and then converts, on the fly, to the user-defined type T. In contrast, std.json.Value.jsonParse returns the representation of the JSON value as is, without converting it to your type.

4 Likes

Thanks yamafaktory! Wish I had read this article before I started!

1 Like

This is awesome! It took some elbow grease to understand what to do with std.json.Value.jsonParse’s source argument, which is of type anytype. It comes without documentation, and I couldn’t find any calls made to it in the official code. Turns out, it wants a std.json.Reader, which I could get from std.json.reader().

In the end, I called it like this:

    var json_reader = std.json.reader(allocator, messages_json.reader());
    const json = try std.json.Value.jsonParse(allocator, &json_reader, .{.max_value_len = 1024*8});

I noticed that the test files are empty for std.json, apart from some missing documentation. I would like to contribute to that. I wonder what the acceptance criteria would be.

This is only true for the distributed version of Zig. There are quite a few tests in the source:

etc

1 Like

Wow, would’ve never checked. :slight_smile:

I think std.json.parseFromTokenSource is the proper way to address what std.json.Value.jsonParse does.

    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = gpa.allocator();
    var json_reader = std.json.reader(allocator,  messages_json.reader());
    const parsed_json = try std.json.parseFromTokenSource(std.json.Value, allocator, &json_reader, .{});
    std.log.info("parseFromTokenSource: {s}\n", .{parsed_json.value.object.get("conversations").?.array.items[0].object.get("id").?.string});