zimdjson JSON Parser for Zig

repository·main·Indexed 41 days ago

https://github.com/ezequielramis/zimdjson

A high-performance JSON parser for Zig utilizing SIMD vector instructions. It features a streaming parser (zimdjson.ondemand.StreamParser) for O(1) memory usage on large files and a reflection-based deserialization interface (zimdjson.ondemand.FullParser) for mapping JSON data into Zig structs.

Tokens
1.1K
Snippets
3
Records
4
Agent score
2%

What's inside zimdjson

  1. Install zimdjson in a Zig project

    main

    To add zimdjson as a dependency to your Zig project, use the zig fetch command in your project root. Then, configure your build.zig to import the dependency module.

    zig fetch --save git+https://github.com/ezequielramis/zimdjson#0.1.1
    const zimdjson = b.dependency("zimdjson", .{});
    exe.root_module.addImport("zimdjson", zimdjson.module("zimdjson"));
  2. Use the streaming parser for large JSON documents

    main

    The zimdjson.ondemand.StreamParser is designed to handle arbitrarily large JSON documents with $O(1)$ memory usage. This is ideal for multi-gigabyte files where you want to avoid loading the entire document into RAM. You can initialize it with .default and use parseFromReader to process data from a reader (like a file).

    const std = @import("std");
    const zimdjson = @import("zimdjson");
    
    pub fn main() !void {
        var gpa = std.heap.GeneralPurposeAllocator(.{}).init;
        const allocator = gpa.allocator();
    
        var parser = zimdjson.ondemand.StreamParser(.default).init;
        defer parser.deinit(allocator);
    
        const file = try std.fs.cwd().openFile("twitter.json", .{});
        defer file.close();
    
        const document = try parser.parseFromReader(allocator, file.reader().any());
    
        const metadata_count = try document.at("search_metadata").at("count").asUnsigned();
        std.debug.print("{} results.\", .{metadata_count});
    }
  3. Deserialize JSON into Zig structs using reflection

    main

    For ergonomic deserialization similar to Rust's Serde, use zimdjson.ondemand.FullParser. This leverages Zig's compile-time reflection to map JSON data directly into predefined Zig struct types. This approach reduces boilerplate and supports complex types like slices and arrays.

    const std = @import("std");
    const zimdjson = @import("zimdjson");
    
    const Film = struct {
        name: []const u8,
        year: u32,
        characters: []const []const u8,
    };
    
    pub fn main() !void {
        var gpa = std.heap.GeneralPurposeAllocator(.{}).init;
        const allocator = gpa.allocator();
    
        var parser = zimdjson.ondemand.FullParser(.default).init;
        defer parser.deinit(allocator);
    
        const json = \
            \{\n        \  "name": "Esperando la carroza",\n        \  "year": 1985,\n        \  "characters": [\n        \    "Mamá Cora",\n        \    "Antonio",\n        \    "Sergio",\n        \    "Emilia",\n        \    "Jorge"\n        \  ]\n        \}\n    ;
    
        const document = try parser.parseFromSlice(allocator, json);
    
        const film = try document.as(Film, allocator, .{});
        defer film.deinit();
    
        // film.value now contains the populated Film struct
    }