Skip to content

Commit

Permalink
Implement a compile command to separately preprocess schemas
Browse files Browse the repository at this point in the history
Signed-off-by: Juan Cruz Viotti <[email protected]>
  • Loading branch information
jviotti committed Jul 15, 2024
1 parent 46fbfa4 commit f5fda09
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ documentation:
- [`jsonschema lint`](./docs/lint.markdown)
- [`jsonschema bundle`](./docs/bundle.markdown) (for inlining remote references in a schema)
- [`jsonschema frame`](./docs/frame.markdown) (for debugging references)
- [`jsonschema compile`](./docs/compile.markdown) (for internal debugging)

Coming Soon
-----------
Expand Down
46 changes: 46 additions & 0 deletions docs/compile.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
Compile
=======

> [!WARNING]
> Only JSON Schema Draft 4, Draft 6, and Draft 7 are supported at this point in
> time. We have plans to support *every* dialect of JSON Schema from Draft 0 to
> Draft 2020-12 soon.
```sh
jsonschema compile <schema.json>
```

Evaluating a JSON Schema is a complex process with a non-trivial associated
performance overhead. For faster evaluation, we internally pre-process a given
JSON Schema into a compiled low-level form. This command allows you to obtain
the schema compilation result as a separate step.

**At least for now, this command is mainly for internal debugging purposes. As
an end-user, you are better served by the [`validate`](./validate.markdown)
command, which internally compiles schemas.**

Examples
--------

For example, consider the following simple schema:

```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"foo": { "type": "string" }
}
}
```

The compilation process will result in something like this:

```
TODO
```

### Compile a JSON Schema

```sh
jsonschema compile path/to/my/schema.json
```
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ add_executable(jsonschema_cli
command_fmt.cc
command_frame.cc
command_bundle.cc
command_compile.cc
command_test.cc
command_lint.cc
command_metaschema.cc
Expand Down
1 change: 1 addition & 0 deletions src/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace intelligence::jsonschema::cli {
auto fmt(const std::span<const std::string> &arguments) -> int;
auto frame(const std::span<const std::string> &arguments) -> int;
auto bundle(const std::span<const std::string> &arguments) -> int;
auto compile(const std::span<const std::string> &arguments) -> int;
auto test(const std::span<const std::string> &arguments) -> int;
auto lint(const std::span<const std::string> &arguments) -> int;
auto validate(const std::span<const std::string> &arguments) -> int;
Expand Down
33 changes: 33 additions & 0 deletions src/command_compile.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <sourcemeta/jsontoolkit/json.h>
#include <sourcemeta/jsontoolkit/jsonschema.h>

#include <cstdlib> // EXIT_SUCCESS
#include <iostream> // std::cout, std::endl

#include "command.h"
#include "utils.h"

auto intelligence::jsonschema::cli::compile(
const std::span<const std::string> &arguments) -> int {
const auto options{parse_options(arguments, {})};

if (options.at("").size() < 1) {
std::cerr
<< "error: This command expects a path to a schema. For example:\n\n"
<< " jsonschema compile path/to/schema.json\n";
return EXIT_FAILURE;
}

const auto schema{sourcemeta::jsontoolkit::from_file(options.at("").front())};

const auto compiled_schema{sourcemeta::jsontoolkit::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
resolver(options, options.contains("h") || options.contains("http")),
sourcemeta::jsontoolkit::default_schema_compiler)};

const sourcemeta::jsontoolkit::JSON result{
sourcemeta::jsontoolkit::to_json(compiled_schema)};
sourcemeta::jsontoolkit::prettify(result, std::cout);
std::cout << std::endl;
return EXIT_SUCCESS;
}
7 changes: 7 additions & 0 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ Global Options:
Frame a schema in-place, displaying schema locations and references
in a human-readable manner.
compile <schema.json>
Pre-process a JSON Schema into JSON Toolkit's low-level JSON-based
compiled form for faster evaluation.
For more documentation, visit https://github.com/Intelligence-AI/jsonschema
)EOF"};

Expand All @@ -69,6 +74,8 @@ auto jsonschema_main(const std::string &program, const std::string &command,
return intelligence::jsonschema::cli::frame(arguments);
} else if (command == "bundle") {
return intelligence::jsonschema::cli::bundle(arguments);
} else if (command == "compile") {
return intelligence::jsonschema::cli::compile(arguments);
} else if (command == "lint") {
return intelligence::jsonschema::cli::lint(arguments);
} else if (command == "validate") {
Expand Down

0 comments on commit f5fda09

Please sign in to comment.