Skip to content

Commit

Permalink
docs: Update README
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Dygalo <dmitry@dygalo.dev>
  • Loading branch information
Stranger6667 committed May 1, 2024
1 parent aa94a4b commit 146f6cd
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 5 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020-2022 Dmitry Dygalo
Copyright (c) 2020-2024 Dmitry Dygalo

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,73 @@ fn main() {
}
```

## Custom keywords

`jsonschema` allows you to implement custom validation logic by defining custom keywords.
To use your own keyword, you need to implement the `Keyword` trait and add it to the `JSONSchema` instance via the `with_keyword` method:

```rust
use jsonschema::{
paths::{JSONPointer, JsonPointerNode},
ErrorIterator, JSONSchema, Keyword, ValidationError,
};
use serde_json::{json, Map, Value};
use std::iter::once;

struct MyCustomValidator;

impl Keyword for MyCustomValidator {
fn validate<'instance>(
&self,
instance: &'instance Value,
instance_path: &JsonPointerNode,
) -> ErrorIterator<'instance> {
// ... validate instance ...
if !instance.is_object() {
let error = ValidationError::custom(
JSONPointer::default(),
instance_path.into(),
instance,
"Boom!",
);
Box::new(once(error))
} else {
Box::new(None.into_iter())
}
}
fn is_valid(&self, instance: &Value) -> bool {
// ... determine if instance is valid ...
true
}
}

// You can create a factory function, or use a closure to create new validator instances.
fn custom_validator_factory<'a>(
// Parent object where your keyword is defined
parent: &'a Map<String, Value>,
// Your keyword value
value: &'a Value,
// JSON Pointer to your keyword within the schema
path: JSONPointer,
) -> Result<Box<dyn Keyword>, ValidationError<'a>> {
// You may return validation error if the keyword is misused for some reason
Ok(Box::new(MyCustomValidator))
}

fn main() {
let schema = json!({"my-type": "my-schema"});
let instance = json!({"a": "b"});
let compiled = JSONSchema::options()
// Register your keyword via a factory function
.with_keyword("my-type", custom_validator_factory)
// Or use a closure
.with_keyword("my-type-with-closure", |_, _, _| Ok(Box::new(MyCustomValidator)))
.compile(&schema)
.expect("A valid schema");
assert!(compiled.is_valid(instance));
}
```

## Reference resolving and TLS

By default, `jsonschema` resolves HTTP references via `reqwest` without TLS support.
Expand Down
11 changes: 7 additions & 4 deletions jsonschema/src/compilation/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -647,9 +647,12 @@ impl CompilationOptions {
/// ## Example
///
/// ```rust
/// # use jsonschema::{ErrorIterator, JSONSchema, paths::{JsonPointerNode, JSONPointer}, Keyword, ValidationError};
/// # use serde_json::{json, Value, Map};
/// # use std::{sync::Arc, iter::once};
/// # use jsonschema::{
/// # paths::{JSONPointer, JsonPointerNode},
/// # ErrorIterator, JSONSchema, Keyword, ValidationError,
/// # };
/// # use serde_json::{json, Map, Value};
/// # use std::iter::once;
///
/// struct MyCustomValidator;
///
Expand Down Expand Up @@ -681,7 +684,7 @@ impl CompilationOptions {
/// // You can create a factory function, or use a closure to create new validator instances.
/// fn custom_validator_factory<'a>(
/// parent: &'a Map<String, Value>,
/// schema: &'a Value,
/// value: &'a Value,
/// path: JSONPointer,
/// ) -> Result<Box<dyn Keyword>, ValidationError<'a>> {
/// Ok(Box::new(MyCustomValidator))
Expand Down

0 comments on commit 146f6cd

Please sign in to comment.