Skip to content

travisstaloch/json-schema-gen

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

json-schema-gen

Generate zig code from arbitrary json data which can parse it.

Web

https://travisstaloch.github.io/

Motivation

When you need to parse arbitrary json in zig, you usually pass std.json.Value to one of the parse() methods. This is convenient but is generally slower and allocates more memory than passing a concrete type.

Also, std.json.Value can be a little akward at times. Here is how it looks to access data from the github api

with std.json.Value:

const url = parsed.value.object.get("items").?
    .array.items[0].object.get("commits_url").?.string;

with generated schema:

const url = parsed.value.items[0].commits_url;

Generate a zig schema

clone or download this project and run the following, replacing examples/1.json with the path to your json file.

$ zig build json -- examples/1.json > /my/project/src/json-schema.zig

parsing     .../json-schema-gen/examples/1.json
schema file .../json-schema-gen/.zig-cache/o/1bcb06dde0b5dc7c91c6fe363f6d75fd/stdout
success!
printing schema to stdout

$ cat /my/project/src/json-schema.zig
pub const Root = []const struct {
    a: struct {
        b: []const struct {
            key: ?[]const u8 = null,
        },
    },
};

Running with --verbose shows how the build system uses json-to-zig-schema.zig to generate a zig schema file in the cache. The schema file is then used by src/main.zig to parse the input examples/1.json file. The json path and generated schema paths are shown along with a 'success!' message or an error trace if parsing fails.

$ zig build json --verbose -- examples/1.json
json-schema-gen/.zig-cache/o/ebdbc614762cd389f778330b79addccd/json-to-zig-schema examples/1.json
# ... omitted
.../json-schema-gen/.zig-cache/o/0ef81ace90ad368f1e00b92e39512af1/parse-json-with-gen-schema examples/1.json

parsing     .../json-schema-gen/examples/1.json
schema file .../json-schema-gen/.zig-cache/o/1bcb06dde0b5dc7c91c6fe363f6d75fd/stdout
success!
printing schema to stdout
# ... omitted

The zig script has a couple options

$ zig build gen -- -h

USAGE: $ json-to-zig-schema <json-file-path> <?options>
  options:
    --debug-json   - add a jsonParse() method to each object which prints field names.
    --dump-schema  - print schema json instead of generating zig code.
    --input-schema - treat input as schema json file and skip build phase.
    --include-test - add a test skeleton to ouptut.

Generate a zig schema from a json schema

  1. generate json schema (optional)
$ zig build
$ zig-out/bin/json-to-zig-schema examples/1.json --dump-schema > /tmp/example-1-schema.json
  1. specify it as input with the --input-schema flag
$ zig-out/bin/json-to-zig-schema /tmp/example-1-schema.json --input-schema
pub const Root = []const struct {
    a: struct {
        b: []const struct {
            key: ?[]const u8 = null,
        },
    },
};

Using generated schema

src/main.zig and src/tests.zig both show how to pass the generated schema file to a std.json.parse() method. If you want to do the same, you can

  1. run zig build json /path/to/my.json and either redirect stdout to a file or pipe to your editor and save it next to your zig project. lets call it json-schema.zig
  • redirect to file: zig build json -- examples/1.json > /my/project/src/json-schema.zig
  • pipe to editor: zig build json -- examples/1.json | nvim -
  1. add this line a zig file where you want to use it: const generated = @import("json-schema.zig");
  2. parse your json.

Troubleshooting parse errors

If your json file won't parse, you can use the --debug-json option to generate zig code which prints field names as they are parsed.

$ zig build json -- examples/1.json --debug-json
# ... omitted
a
b
key
success!
# ... omitted

Hopefully that narrows your search for the problem json field and helps decide what edits to make to json-schema.zig.

Or if you find a way to improve the schema gen script to fix your parse error, patches are welcome. Please add a reproduction of your parse error to examples/ and a test case to src/tests.zig. You'll need to add entries for your file to example_mods and example_fmts.

About

Generate zig code from arbitrary json which can parse it

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published