This commit is contained in:
Cristian Le 2023-09-22 17:09:50 +02:00 committed by GitHub
commit 90ece4306b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 385 additions and 143 deletions

163
.gitignore vendored
View File

@ -1,6 +1,165 @@
build*/
*.sw?
cmake-build-*
venv
env
compile_commands.json
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
.idea/
### Project specific
CMakeUserPresets.json

View File

@ -26,6 +26,18 @@ repos:
additional_dependencies:
- mdformat-gfm
- mdformat-tables
exclude: docs\/.*
- repo: https://github.com/executablebooks/mdformat
# TODO: Temporarily separate docs formatiing
# https://github.com/executablebooks/mdformat/issues/234
# TODO: Disabled due to lack of colon-fence support
rev: 0.7.16
hooks:
- id: mdformat
stages: [ manual ]
additional_dependencies:
- mdformat-myst
files: doc\/(?!README).*\.md$
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.23.0
hooks:

13
.readthedocs.yaml Normal file
View File

@ -0,0 +1,13 @@
version: 2
python:
install:
- path: .
extra_requirements:
- docs
build:
os: ubuntu-22.04
tools:
python: "3.11"
sphinx:
configuration: docs/conf.py

173
README.md
View File

@ -1,8 +1,6 @@
[![Build Status](https://travis-ci.org/pboettch/json-schema-validator.svg?branch=master)](https://travis-ci.org/pboettch/json-schema-validator)
# JSON schema validator for JSON for Modern C++
# What is it?
<!-- SHINX-START -->
This is a C++ library for validating JSON documents based on a
[JSON Schema](http://json-schema.org/) which itself should validate with
@ -15,146 +13,47 @@ Niels Lohmann et al develop a great JSON parser for C++ called [JSON for Modern
C++](https://github.com/nlohmann/json). This validator is based on this
library, hence the name.
External documentation is missing as well. However the API of the validator
is rather simple.
## Getting started
# New in version 2
Currently, this package only offers a C++ library interface, and is only
available via cmake's `FetchContent` and conan. It is highly recommended
to use cmake to link to this library
Although significant changes have been done for the 2nd version
(a complete rewrite) the API is compatible with the 1.0.0 release. Except for
the namespace which is now `nlohmann::json_schema`.
Dependencies:
Version **2** supports JSON schema draft 7, whereas 1 was supporting draft 4
only. Please update your schemas.
- NLohmann's Json library: At least **3.6.0**
(See Github actions for officially tested versions)
The primary change in 2 is the way a schema is used. While in version 1 the schema was
kept as a JSON-document and used again and again during validation, in version 2 the schema
is parsed into compiled C++ objects which are then used during validation. There are surely
still optimizations to be done, but validation speed has improved by factor 100
or more.
### CMake configuration
# Design goals
<!-- SHINX-CMAKE-START -->
The main goal of this validator is to produce *human-comprehensible* error
messages if a JSON-document/instance does not comply to its schema.
Bellow is a minimum cmake configuration file using `FetchContent`:
By default this is done with exceptions thrown at the users with a helpful
message telling what's wrong with the document while validating.
```cmake
cmake_minimum_required(VERSION 3.11)
Starting with **2.0.0** the user can pass a `json_schema::basic_error_handler`-derived
object along with the instance to validate to receive a callback each time
a validation error occurs and decide what to do (throwing, counting, collecting).
project(example)
Another goal was to use Niels Lohmann's JSON-library. This is why the validator
lives in his namespace.
include(FetchContent)
# Thread-safety
FetchContent_Declare(nlohmann_json_schema_validator
GIT_REPOSITORY pboettch/json-schema-validator
# Please use a specific version tag
GIT_TAG main
)
FetchContent_MakeAvailable(nlohmann_json_schema_validator)
Instance validation is thread-safe and the same validator-object can be used by
different threads:
The validate method is `const` which indicates the object is not modified when
being called:
```C++
json json_validator::validate(const json &) const;
add_executable(example main.cpp)
target_link_libraries(example PRIVATE nlohmann_json_schema_validator::validator)
```
Validator-object creation however is not thread-safe. A validator has to be
created in one (main?) thread once.
<!-- SHINX-CMAKE-END -->
# Weaknesses
For more details about the available cmake options and recommended configurations
see [docs/cmake](docs/cmake/index.md)
Numerical validation uses nlohmann-json's integer, unsigned and floating point
types, depending on if the schema type is "integer" or "number". Bignum
(i.e. arbitrary precision and range) is not supported at this time.
# Building
This library is based on Niels Lohmann's JSON-library and thus has
a build-dependency to it.
Currently at least version **3.6.0** of NLohmann's JSON library
is required.
Various methods using CMake can be used to build this project.
## Build out-of-source
Do not run cmake inside the source-dir. Rather create a dedicated build-dir:
```Bash
git clone https://github.com/pboettch/json-schema-validator.git
cd json-schema-validator
mkdir build
cd build
cmake [..]
make
make install # if needed
ctest # run unit, non-regression and test-suite tests
```
## Building as shared library
By default a static library is built. Shared libraries can be generated by using
the `BUILD_SHARED_LIBS`-cmake variable:
In your initial call to cmake simply add:
```bash
cmake [..] -DBUILD_SHARED_LIBS=ON [..]
```
## nlohmann-json integration
As nlohmann-json is a dependency, this library tries find it.
The cmake-configuration first checks if nlohmann-json is available as a cmake-target. This may be the case, because it is used as a submodule in a super-project which already provides and uses nlohmann-json.
Otherwise, it calls `find_package` for nlohmann-json and requires nlohmann-json to be installed on the system.
### Building with Hunter package manager
To enable access to nlohmann json library, Hunter can be used. Just run with `JSON_VALIDATOR_HUNTER=ON` option. No further dependencies needed
```bash
cmake [..] -DJSON_VALIDATOR_HUNTER=ON [..]
```
### Building as a CMake-subdirectory from within another project
Adding this library as a subdirectory to a parent project is one way of
building it.
If the parent project already used `find_package()` to find the CMake-package of nlohmann_json or includes it as a submodule likewise.
### Building directly, finding a CMake-package. (short)
When nlohmann-json has been installed, it provides files which allows
CMake's `find_package()` to be used.
This library is using this mechanism if `nlohmann_json::nlohmann_json`-target
does not exist.
### Install
Since version 2.1.0 this library can be installed and CMake-package-files will be
created accordingly. If the installation of nlohmann-json and this library
is done into default unix-system-paths CMake will be able to find this
library by simply doing:
```CMake
find_package(nlohmann_json_schema_validator REQUIRED)
```
and
```CMake
target_link_libraries(<your-target> [..] nlohmann_json_schema_validator)
```
to build and link.
## Code
### Api example
See also `app/json-schema-validate.cpp`.
@ -252,7 +151,7 @@ int main()
}
```
# Compliance
## Compliance
There is an application which can be used for testing the validator with the
[JSON-Schema-Test-Suite](https://github.com/json-schema-org/JSON-Schema-Test-Suite).
@ -263,7 +162,7 @@ cmake-variable `JSON_SCHEMA_TEST_SUITE_PATH` will enable the test-target(s).
All required tests are **OK**.
# Format
## Format
Optionally JSON-schema-validator can validate predefined or user-defined formats.
Therefore a format-checker-function can be provided by the user which is called by
@ -287,7 +186,7 @@ json_validator validator(nullptr, // or loader-callback
my_format_checker); // create validator
```
## Default Checker
### Default Checker
The library contains a default-checker, which does some checks. It needs to be
provided manually to the constructor of the validator:
@ -301,7 +200,7 @@ Supported formats: `date-time, date, time, email, hostname, ipv4, ipv6, uuid, re
More formats can be added in `src/string-format-check.cpp`. Please contribute implementions for missing json schema draft formats.
## Default value processing
### Default value processing
As a result of the validation, the library returns a json patch including the default values of the specified schema.
@ -355,12 +254,4 @@ The example above will output the specified default values `{"height":10,"width"
> Note that the default value specified in a `$ref` may be overridden by the current instance location. Also note that this behavior will break draft-7, but it is compliant to newer drafts (e.g. `2019-09` or `2020-12`).
# Contributing
This project uses [`pre-commit`](https://pre-commit.com/) to enforce style-checks. Please install and run it before
creating commits and making pull requests.
```console
$ pip install pre-commit
$ pre-commit install
```
<!-- SHINX-END -->

15
docs/CONTRIBUTING.md Normal file
View File

@ -0,0 +1,15 @@
# Contributing Guidelines
Pull request are more than welcome on the
[GitHub page](https://github.com/pboettch/json-schema-validator).
## Development environment
This project uses [`pre-commit`](https://pre-commit.com/) to enforce style-checks.
These checks are enforced in the GitHub Actions, but it is encouraged to install
a development environment locally as well.
```console
$ pip install -e .[dev]
$ pre-commit install
```

16
docs/changelog.md Normal file
View File

@ -0,0 +1,16 @@
# Changelog
## New in version 2
Although significant changes have been done for the 2nd version
(a complete rewrite) the API is compatible with the 1.0.0 release. Except for
the namespace which is now `nlohmann::json_schema`.
Version **2** supports JSON schema draft 7, whereas 1 was supporting draft 4
only. Please update your schemas.
The primary change in 2 is the way a schema is used. While in version 1 the schema was
kept as a JSON-document and used again and again during validation, in version 2 the schema
is parsed into compiled C++ objects which are then used during validation. There are surely
still optimizations to be done, but validation speed has improved by factor 100
or more.

3
docs/cmake/advanced.md Normal file
View File

@ -0,0 +1,3 @@
# Advanced usage
## Working with `FetchCotent`

16
docs/cmake/index.md Normal file
View File

@ -0,0 +1,16 @@
# CMake configuration guide
:::{toctree}
---
maxdepth: 2
glob: true
hidden: true
---
:::
:::{include} ../../README.md
---
start-after: <!-- SHINX-CMAKE-START -->
end-before: <!-- SHINX-CMAKE-END -->
---
:::

5
docs/cmake/options.md Normal file
View File

@ -0,0 +1,5 @@
# Configuration options
## Available options
## Working with CMake options

5
docs/cmake/presets.md Normal file
View File

@ -0,0 +1,5 @@
# CMake Presets
## Available presets
## Working with presets

26
docs/conf.py Normal file
View File

@ -0,0 +1,26 @@
project = 'Json Schema Validator'
copyright = '2023, Patrick Boettcher'
author = 'Patrick Boettcher'
extensions = [
"myst_parser",
]
templates_path = []
exclude_patterns = [
'build',
'_build',
'Thumbs.db',
'.DS_Store',
"README.md",
]
source_suffix = [".md"]
html_theme = 'sphinx_rtd_theme'
html_static_path = ['_static']
myst_enable_extensions = [
"tasklist",
"colon_fence",
]

20
docs/index.md Normal file
View File

@ -0,0 +1,20 @@
# Json-Schema-Validator
:::{toctree}
---
maxdepth: 2
glob: true
hidden: true
---
CONTRIBUTING
changelog
roadmap
cmake/index.md
:::
:::{include} ../README.md
---
start-after: <!-- SHINX-START -->
end-before: <!-- SHINX-END -->
---
:::

37
docs/roadmap.md Normal file
View File

@ -0,0 +1,37 @@
# Roadmap
## Design goals
The main goal of this validator is to produce *human-comprehensible* error
messages if a JSON-document/instance does not comply to its schema.
By default this is done with exceptions thrown at the users with a helpful
message telling what's wrong with the document while validating.
Starting with **2.0.0** the user can pass a `json_schema::basic_error_handler`-derived
object along with the instance to validate to receive a callback each time
a validation error occurs and decide what to do (throwing, counting, collecting).
Another goal was to use Niels Lohmann's JSON-library. This is why the validator
lives in his namespace.
## Thread-safety
Instance validation is thread-safe and the same validator-object can be used by
different threads:
The validate method is `const` which indicates the object is not modified when
being called:
```C++
json json_validator::validate(const json &) const;
```
Validator-object creation however is not thread-safe. A validator has to be
created in one (main?) thread once.
## Weaknesses
Numerical validation uses nlohmann-json's integer, unsigned and floating point
types, depending on if the schema type is "integer" or "number". Bignum
(i.e. arbitrary precision and range) is not supported at this time.

24
pyproject.toml Normal file
View File

@ -0,0 +1,24 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "json-schema-validator-dev"
version = "0.0.0"
description = "Development environment json-schenma-validator"
readme = "README.md"
license = { file = "LICENSE" }
[project.optional-dependencies]
docs = [
"sphinx >= 6.0",
"sphinx-rtd-theme",
"myst-parser",
]
dev = [
"pre-commit",
]
[tool.setuptools]
packages = []