feat: Use meta-schemas to validate input schemas
This commit is contained in:
parent
1212e8893b
commit
5e65010387
|
@ -2,6 +2,15 @@
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- **BREAKING**: Meta-schema validation for input schemas. By default, all input schemas are validated with their respective meta-schemas
|
||||
and instead of `CompilationError` there will be the usual `ValidationError`. [#198](https://github.com/Stranger6667/jsonschema-rs/issues/198)
|
||||
|
||||
### Removed
|
||||
|
||||
- `CompilationError`. Use `ValidationError` instead.
|
||||
|
||||
## [0.9.1] - 2021-06-17
|
||||
|
||||
### Fixed
|
||||
|
|
14
README.md
14
README.md
|
@ -22,13 +22,13 @@ jsonschema = "0.9"
|
|||
To validate documents against some schema and get validation errors (if any):
|
||||
|
||||
```rust
|
||||
use jsonschema::{JSONSchema, Draft, CompilationError};
|
||||
use jsonschema::{Draft, JSONSchema};
|
||||
use serde_json::json;
|
||||
|
||||
fn main() -> Result<(), CompilationError> {
|
||||
fn main() {
|
||||
let schema = json!({"maxLength": 5});
|
||||
let instance = json!("foo");
|
||||
let compiled = JSONSchema::compile(&schema)?;
|
||||
let compiled = JSONSchema::compile(&schema).expect("A valid schema");
|
||||
let result = compiled.validate(&instance);
|
||||
if let Err(errors) = result {
|
||||
for error in errors {
|
||||
|
@ -38,7 +38,6 @@ fn main() -> Result<(), CompilationError> {
|
|||
);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -61,17 +60,16 @@ fn main() {
|
|||
Or use a compiled schema (preferred):
|
||||
|
||||
```rust
|
||||
use jsonschema::{JSONSchema, Draft, CompilationError};
|
||||
use jsonschema::{Draft, JSONSchema};
|
||||
use serde_json::json;
|
||||
|
||||
fn main() -> Result<(), CompilationError> {
|
||||
fn main() {
|
||||
let schema = json!({"maxLength": 5});
|
||||
let instance = json!("foo");
|
||||
// Draft is detected automatically
|
||||
// with fallback to Draft7
|
||||
let compiled = JSONSchema::compile(&schema)?;
|
||||
let compiled = JSONSchema::compile(&schema).expect("A valid schema");
|
||||
assert!(compiled.is_valid(&instance));
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -2,6 +2,15 @@
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- **BREAKING**: Meta-schema validation for input schemas. By default, all input schemas are validated with their respective meta-schemas
|
||||
and instead of `CompilationError` there will be the usual `ValidationError`. [#198](https://github.com/Stranger6667/jsonschema-rs/issues/198)
|
||||
|
||||
### Removed
|
||||
|
||||
- `CompilationError`. Use `ValidationError` instead.
|
||||
|
||||
## [0.9.1] - 2021-06-17
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -28,16 +28,11 @@ const DRAFT4: u8 = 4;
|
|||
|
||||
create_exception!(jsonschema_rs, ValidationError, exceptions::PyValueError);
|
||||
|
||||
#[derive(Debug)]
|
||||
enum JSONSchemaError {
|
||||
Compilation(jsonschema::CompilationError),
|
||||
}
|
||||
struct ValidationErrorWrapper<'a>(jsonschema::ValidationError<'a>);
|
||||
|
||||
impl From<JSONSchemaError> for PyErr {
|
||||
fn from(error: JSONSchemaError) -> PyErr {
|
||||
exceptions::PyValueError::new_err(match error {
|
||||
JSONSchemaError::Compilation(_) => "Invalid schema",
|
||||
})
|
||||
impl<'a> From<ValidationErrorWrapper<'a>> for PyErr {
|
||||
fn from(error: ValidationErrorWrapper<'a>) -> PyErr {
|
||||
ValidationError::new_err(to_error_message(&error.0))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,12 +65,9 @@ fn make_options(
|
|||
fn raise_on_error(compiled: &jsonschema::JSONSchema, instance: &PyAny) -> PyResult<()> {
|
||||
let instance = ser::to_value(instance)?;
|
||||
let result = compiled.validate(&instance);
|
||||
let error = if let Some(mut errors) = result.err() {
|
||||
// If we have `Err` case, then the iterator is not empty
|
||||
Some(errors.next().expect("Iterator should not be empty"))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let error = result
|
||||
.err()
|
||||
.map(|mut errors| errors.next().expect("Iterator should not be empty"));
|
||||
error.map_or_else(
|
||||
|| Ok(()),
|
||||
|err| {
|
||||
|
@ -127,9 +119,7 @@ fn is_valid(
|
|||
) -> PyResult<bool> {
|
||||
let options = make_options(draft, with_meta_schemas)?;
|
||||
let schema = ser::to_value(schema)?;
|
||||
let compiled = options
|
||||
.compile(&schema)
|
||||
.map_err(JSONSchemaError::Compilation)?;
|
||||
let compiled = options.compile(&schema).map_err(ValidationErrorWrapper)?;
|
||||
let instance = ser::to_value(instance)?;
|
||||
Ok(compiled.is_valid(&instance))
|
||||
}
|
||||
|
@ -155,9 +145,7 @@ fn validate(
|
|||
) -> PyResult<()> {
|
||||
let options = make_options(draft, with_meta_schemas)?;
|
||||
let schema = ser::to_value(schema)?;
|
||||
let compiled = options
|
||||
.compile(&schema)
|
||||
.map_err(JSONSchemaError::Compilation)?;
|
||||
let compiled = options.compile(&schema).map_err(ValidationErrorWrapper)?;
|
||||
raise_on_error(&compiled, instance)
|
||||
}
|
||||
|
||||
|
@ -187,9 +175,7 @@ impl JSONSchema {
|
|||
let raw_schema = ser::to_value(schema)?;
|
||||
let schema: &'static Value = Box::leak(Box::new(raw_schema));
|
||||
Ok(JSONSchema {
|
||||
schema: options
|
||||
.compile(schema)
|
||||
.map_err(JSONSchemaError::Compilation)?,
|
||||
schema: options.compile(schema).map_err(ValidationErrorWrapper)?,
|
||||
raw_schema: schema,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ def test_recursive_list():
|
|||
@pytest.mark.parametrize(
|
||||
"schema, draft, error",
|
||||
(
|
||||
([], None, "Invalid schema"),
|
||||
([], None, r'\[\] is not of types "boolean", "object"'),
|
||||
({}, 5, "Unknown draft: 5"),
|
||||
),
|
||||
)
|
||||
|
|
|
@ -5,11 +5,8 @@ pub(crate) mod context;
|
|||
pub(crate) mod options;
|
||||
|
||||
use crate::{
|
||||
error::{CompilationError, ErrorIterator},
|
||||
keywords,
|
||||
keywords::Validators,
|
||||
paths::InstancePath,
|
||||
resolver::Resolver,
|
||||
error::ErrorIterator, keywords, keywords::Validators, paths::InstancePath, resolver::Resolver,
|
||||
ValidationError,
|
||||
};
|
||||
use context::CompilationContext;
|
||||
use options::CompilationOptions;
|
||||
|
@ -54,7 +51,7 @@ impl<'a> JSONSchema<'a> {
|
|||
/// Compile the input schema into a validation tree.
|
||||
///
|
||||
/// The method is equivalent to `JSONSchema::options().compile(schema)`
|
||||
pub fn compile(schema: &'a Value) -> Result<JSONSchema<'a>, CompilationError> {
|
||||
pub fn compile(schema: &'a Value) -> Result<JSONSchema<'a>, ValidationError<'a>> {
|
||||
Self::options().compile(schema)
|
||||
}
|
||||
|
||||
|
@ -87,10 +84,10 @@ impl<'a> JSONSchema<'a> {
|
|||
|
||||
/// Compile JSON schema into a tree of validators.
|
||||
#[inline]
|
||||
pub(crate) fn compile_validators(
|
||||
schema: &Value,
|
||||
context: &CompilationContext,
|
||||
) -> Result<Validators, CompilationError> {
|
||||
pub(crate) fn compile_validators<'a, 'c>(
|
||||
schema: &'a Value,
|
||||
context: &'c CompilationContext,
|
||||
) -> Result<Validators, ValidationError<'a>> {
|
||||
let context = context.push(schema)?;
|
||||
match schema {
|
||||
Value::Bool(value) => match value {
|
||||
|
@ -105,7 +102,7 @@ pub(crate) fn compile_validators(
|
|||
Ok(vec![keywords::ref_::compile(schema, reference, &context)
|
||||
.expect("Should always return Some")?])
|
||||
} else {
|
||||
Err(CompilationError::SchemaError)
|
||||
Err(ValidationError::schema(schema))
|
||||
}
|
||||
} else {
|
||||
let mut validators = Vec::with_capacity(object.len());
|
||||
|
@ -119,7 +116,7 @@ pub(crate) fn compile_validators(
|
|||
Ok(validators)
|
||||
}
|
||||
}
|
||||
_ => Err(CompilationError::SchemaError),
|
||||
_ => Err(ValidationError::schema(schema)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,28 +5,49 @@ use crate::{
|
|||
DEFAULT_CONTENT_ENCODING_CHECKS_AND_CONVERTERS,
|
||||
},
|
||||
content_media_type::{ContentMediaTypeCheckType, DEFAULT_CONTENT_MEDIA_TYPE_CHECKS},
|
||||
error::CompilationError,
|
||||
resolver::Resolver,
|
||||
schemas,
|
||||
schemas, ValidationError,
|
||||
};
|
||||
use ahash::AHashMap;
|
||||
use serde_json::Value;
|
||||
|
||||
use std::{borrow::Cow, fmt};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref META_SCHEMAS: AHashMap<String, Value> = {
|
||||
static ref DRAFT4:serde_json::Value = serde_json::from_str(include_str!("../../meta_schemas/draft4.json")).expect("Valid schema!");
|
||||
static ref DRAFT6:serde_json::Value = serde_json::from_str(include_str!("../../meta_schemas/draft6.json")).expect("Valid schema!");
|
||||
static ref DRAFT7:serde_json::Value = serde_json::from_str(include_str!("../../meta_schemas/draft7.json")).expect("Valid schema!");
|
||||
|
||||
static ref META_SCHEMAS: AHashMap<String, serde_json::Value> = {
|
||||
let mut store = AHashMap::with_capacity(3);
|
||||
store.insert(
|
||||
"http://json-schema.org/draft-04/schema".to_string(),
|
||||
serde_json::from_str(include_str!("../../meta_schemas/draft4.json")).expect("Valid schema!")
|
||||
DRAFT4.clone()
|
||||
);
|
||||
store.insert(
|
||||
"http://json-schema.org/draft-06/schema".to_string(),
|
||||
serde_json::from_str(include_str!("../../meta_schemas/draft6.json")).expect("Valid schema!")
|
||||
DRAFT6.clone()
|
||||
);
|
||||
store.insert(
|
||||
"http://json-schema.org/draft-07/schema".to_string(),
|
||||
serde_json::from_str(include_str!("../../meta_schemas/draft7.json")).expect("Valid schema!")
|
||||
DRAFT7.clone()
|
||||
);
|
||||
store
|
||||
};
|
||||
|
||||
static ref META_SCHEMA_VALIDATORS: AHashMap<schemas::Draft, JSONSchema<'static>> = {
|
||||
let mut store = AHashMap::with_capacity(3);
|
||||
const EXPECT_MESSAGE: &str = "Valid meta-schema!";
|
||||
store.insert(
|
||||
schemas::Draft::Draft4,
|
||||
JSONSchema::options().without_schema_validation().compile(&DRAFT4).expect(EXPECT_MESSAGE)
|
||||
);
|
||||
store.insert(
|
||||
schemas::Draft::Draft6,
|
||||
JSONSchema::options().without_schema_validation().compile(&DRAFT6).expect(EXPECT_MESSAGE)
|
||||
);
|
||||
store.insert(
|
||||
schemas::Draft::Draft7,
|
||||
JSONSchema::options().without_schema_validation().compile(&DRAFT7).expect(EXPECT_MESSAGE)
|
||||
);
|
||||
store
|
||||
};
|
||||
|
@ -36,13 +57,26 @@ lazy_static::lazy_static! {
|
|||
///
|
||||
/// Using a `CompilationOptions` instance you can configure the supported draft,
|
||||
/// content media types and more (check the exposed methods)
|
||||
#[derive(Clone, Default)]
|
||||
#[derive(Clone)]
|
||||
pub struct CompilationOptions {
|
||||
draft: Option<schemas::Draft>,
|
||||
content_media_type_checks: AHashMap<&'static str, Option<ContentMediaTypeCheckType>>,
|
||||
content_encoding_checks_and_converters:
|
||||
AHashMap<&'static str, Option<(ContentEncodingCheckType, ContentEncodingConverterType)>>,
|
||||
store: AHashMap<String, Value>,
|
||||
store: AHashMap<String, serde_json::Value>,
|
||||
validate_schema: bool,
|
||||
}
|
||||
|
||||
impl Default for CompilationOptions {
|
||||
fn default() -> Self {
|
||||
CompilationOptions {
|
||||
validate_schema: true,
|
||||
draft: Default::default(),
|
||||
content_media_type_checks: Default::default(),
|
||||
content_encoding_checks_and_converters: Default::default(),
|
||||
store: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CompilationOptions {
|
||||
|
@ -51,7 +85,10 @@ impl CompilationOptions {
|
|||
}
|
||||
|
||||
/// Compile `schema` into `JSONSchema` using the currently defined options.
|
||||
pub fn compile<'a>(&self, schema: &'a Value) -> Result<JSONSchema<'a>, CompilationError> {
|
||||
pub fn compile<'a>(
|
||||
&self,
|
||||
schema: &'a serde_json::Value,
|
||||
) -> Result<JSONSchema<'a>, ValidationError<'a>> {
|
||||
// Draft is detected in the following precedence order:
|
||||
// - Explicitly specified;
|
||||
// - $schema field in the document;
|
||||
|
@ -79,6 +116,17 @@ impl CompilationOptions {
|
|||
let resolver = Resolver::new(draft, &scope, schema, self.store.clone())?;
|
||||
let context = CompilationContext::new(scope, processed_config);
|
||||
|
||||
if self.validate_schema {
|
||||
if let Some(mut errors) = META_SCHEMA_VALIDATORS
|
||||
.get(&draft)
|
||||
.expect("Existing draft")
|
||||
.validate(schema)
|
||||
.err()
|
||||
{
|
||||
return Err(errors.next().expect("Should have at least one element"));
|
||||
}
|
||||
}
|
||||
|
||||
let mut validators = compile_validators(schema, &context)?;
|
||||
validators.shrink_to_fit();
|
||||
|
||||
|
@ -295,10 +343,21 @@ impl CompilationOptions {
|
|||
/// Add a new document to the store. It works as a cache to avoid making additional network
|
||||
/// calls to remote schemas via the `$ref` keyword.
|
||||
#[inline]
|
||||
pub fn with_document(&mut self, id: String, document: Value) -> &mut Self {
|
||||
pub fn with_document(&mut self, id: String, document: serde_json::Value) -> &mut Self {
|
||||
self.store.insert(id, document);
|
||||
self
|
||||
}
|
||||
|
||||
/// Do not perform schema validation during compilation.
|
||||
/// This method is only used to disable meta-schema validation for meta-schemas itself to avoid
|
||||
/// infinite recursion.
|
||||
/// The end-user will still receive `ValidationError` that are crafted manually during
|
||||
/// compilation.
|
||||
#[inline]
|
||||
pub(crate) fn without_schema_validation(&mut self) -> &mut Self {
|
||||
self.validate_schema = false;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for CompilationOptions {
|
||||
|
|
|
@ -7,45 +7,13 @@ use serde_json::{Map, Number, Value};
|
|||
use std::{
|
||||
borrow::Cow,
|
||||
error, fmt,
|
||||
fmt::{Error, Formatter},
|
||||
fmt::Formatter,
|
||||
io,
|
||||
iter::{empty, once},
|
||||
str::Utf8Error,
|
||||
string::FromUtf8Error,
|
||||
};
|
||||
|
||||
/// The error type that happens when the input schema is not valid.
|
||||
///
|
||||
/// It includes cases when during validation a reference is resolved into an invalid schema,
|
||||
/// which we can't know upfront because schemas can be in remote locations.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum CompilationError {
|
||||
/// Invalid schema structure
|
||||
SchemaError,
|
||||
}
|
||||
|
||||
impl error::Error for CompilationError {}
|
||||
|
||||
impl fmt::Display for CompilationError {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
|
||||
write!(f, "Schema compilation error")
|
||||
}
|
||||
}
|
||||
|
||||
impl From<fancy_regex::Error> for CompilationError {
|
||||
#[inline]
|
||||
fn from(_: fancy_regex::Error) -> Self {
|
||||
CompilationError::SchemaError
|
||||
}
|
||||
}
|
||||
impl From<url::ParseError> for CompilationError {
|
||||
#[inline]
|
||||
fn from(_: url::ParseError) -> Self {
|
||||
CompilationError::SchemaError
|
||||
}
|
||||
}
|
||||
|
||||
/// An error that can occur during validation.
|
||||
#[derive(Debug)]
|
||||
pub struct ValidationError<'a> {
|
||||
|
@ -612,13 +580,23 @@ impl<'a> ValidationError<'a> {
|
|||
kind: ValidationErrorKind::Reqwest { error },
|
||||
}
|
||||
}
|
||||
pub(crate) fn schema() -> ValidationError<'a> {
|
||||
|
||||
pub(crate) fn schema(instance: &'a Value) -> ValidationError<'a> {
|
||||
ValidationError {
|
||||
instance_path: JSONPointer::default(),
|
||||
instance: Cow::Borrowed(instance),
|
||||
kind: ValidationErrorKind::Schema,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn null_schema() -> ValidationError<'a> {
|
||||
ValidationError {
|
||||
instance_path: JSONPointer::default(),
|
||||
instance: Cow::Owned(Value::Null),
|
||||
kind: ValidationErrorKind::Schema,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn single_type_error(
|
||||
instance_path: JSONPointer,
|
||||
instance: &'a Value,
|
||||
|
@ -671,12 +649,6 @@ impl<'a> ValidationError<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<CompilationError> for ValidationError<'_> {
|
||||
#[inline]
|
||||
fn from(_: CompilationError) -> Self {
|
||||
ValidationError::schema()
|
||||
}
|
||||
}
|
||||
impl error::Error for ValidationError<'_> {}
|
||||
impl From<serde_json::Error> for ValidationError<'_> {
|
||||
#[inline]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{compile_validators, context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::{boolean::FalseValidator, format_validators, CompilationResult, Validators},
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -13,11 +13,11 @@ pub(crate) struct AdditionalItemsObjectValidator {
|
|||
}
|
||||
impl AdditionalItemsObjectValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
items_count: usize,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
let validators = compile_validators(schema, context)?;
|
||||
Ok(Box::new(AdditionalItemsObjectValidator {
|
||||
validators,
|
||||
|
@ -72,7 +72,7 @@ pub(crate) struct AdditionalItemsBooleanValidator {
|
|||
}
|
||||
impl AdditionalItemsBooleanValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(items_count: usize) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(items_count: usize) -> CompilationResult<'a> {
|
||||
Ok(Box::new(AdditionalItemsBooleanValidator { items_count }))
|
||||
}
|
||||
}
|
||||
|
@ -111,11 +111,11 @@ impl ToString for AdditionalItemsBooleanValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
pub(crate) fn compile<'a>(
|
||||
parent: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
if let Some(items) = parent.get("items") {
|
||||
match items {
|
||||
Value::Object(_) => None,
|
||||
|
@ -140,7 +140,7 @@ pub(crate) fn compile(
|
|||
Some(FalseValidator::compile())
|
||||
}
|
||||
}
|
||||
_ => Some(Err(CompilationError::SchemaError)),
|
||||
_ => Some(Err(ValidationError::schema(schema))),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
//! Each valid combination of these keywords has a validator here.
|
||||
use crate::{
|
||||
compilation::{compile_validators, context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::{format_validators, CompilationResult, Validators},
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -76,7 +76,7 @@ macro_rules! dynamic_map {
|
|||
))
|
||||
}
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::null_schema()))
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
@ -127,20 +127,20 @@ macro_rules! validate {
|
|||
}};
|
||||
}
|
||||
|
||||
fn compile_small_map(
|
||||
map: &Map<String, Value>,
|
||||
fn compile_small_map<'a>(
|
||||
map: &'a Map<String, Value>,
|
||||
context: &CompilationContext,
|
||||
) -> Result<SmallValidatorsMap, CompilationError> {
|
||||
) -> Result<SmallValidatorsMap, ValidationError<'a>> {
|
||||
let mut properties = Vec::with_capacity(map.len());
|
||||
for (key, subschema) in map {
|
||||
properties.push((key.clone(), compile_validators(subschema, context)?));
|
||||
}
|
||||
Ok(properties)
|
||||
}
|
||||
fn compile_big_map(
|
||||
map: &Map<String, Value>,
|
||||
fn compile_big_map<'a>(
|
||||
map: &'a Map<String, Value>,
|
||||
context: &CompilationContext,
|
||||
) -> Result<BigValidatorsMap, CompilationError> {
|
||||
) -> Result<BigValidatorsMap, ValidationError<'a>> {
|
||||
let mut properties = AHashMap::with_capacity(map.len());
|
||||
for (key, subschema) in map {
|
||||
properties.insert(key.clone(), compile_validators(subschema, context)?);
|
||||
|
@ -168,7 +168,10 @@ pub(crate) struct AdditionalPropertiesValidator {
|
|||
}
|
||||
impl AdditionalPropertiesValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(schema: &Value, context: &CompilationContext) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(AdditionalPropertiesValidator {
|
||||
validators: compile_validators(schema, context)?,
|
||||
}))
|
||||
|
@ -231,7 +234,7 @@ impl ToString for AdditionalPropertiesValidator {
|
|||
pub(crate) struct AdditionalPropertiesFalseValidator {}
|
||||
impl AdditionalPropertiesFalseValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new(AdditionalPropertiesFalseValidator {}))
|
||||
}
|
||||
}
|
||||
|
@ -287,10 +290,10 @@ pub(crate) struct AdditionalPropertiesNotEmptyFalseValidator<M: PropertiesValida
|
|||
}
|
||||
impl AdditionalPropertiesNotEmptyFalseValidator<SmallValidatorsMap> {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
map: &Map<String, Value>,
|
||||
pub(crate) fn compile<'a>(
|
||||
map: &'a Map<String, Value>,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(AdditionalPropertiesNotEmptyFalseValidator {
|
||||
properties: compile_small_map(map, context)?,
|
||||
}))
|
||||
|
@ -298,10 +301,10 @@ impl AdditionalPropertiesNotEmptyFalseValidator<SmallValidatorsMap> {
|
|||
}
|
||||
impl AdditionalPropertiesNotEmptyFalseValidator<BigValidatorsMap> {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
map: &Map<String, Value>,
|
||||
pub(crate) fn compile<'a>(
|
||||
map: &'a Map<String, Value>,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(AdditionalPropertiesNotEmptyFalseValidator {
|
||||
properties: compile_big_map(map, context)?,
|
||||
}))
|
||||
|
@ -385,11 +388,11 @@ pub(crate) struct AdditionalPropertiesNotEmptyValidator<M: PropertiesValidatorsM
|
|||
}
|
||||
impl AdditionalPropertiesNotEmptyValidator<SmallValidatorsMap> {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
map: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
map: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(AdditionalPropertiesNotEmptyValidator {
|
||||
properties: compile_small_map(map, context)?,
|
||||
validators: compile_validators(schema, context)?,
|
||||
|
@ -398,11 +401,11 @@ impl AdditionalPropertiesNotEmptyValidator<SmallValidatorsMap> {
|
|||
}
|
||||
impl AdditionalPropertiesNotEmptyValidator<BigValidatorsMap> {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
map: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
map: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(AdditionalPropertiesNotEmptyValidator {
|
||||
properties: compile_big_map(map, context)?,
|
||||
validators: compile_validators(schema, context)?,
|
||||
|
@ -499,11 +502,11 @@ pub(crate) struct AdditionalPropertiesWithPatternsValidator {
|
|||
}
|
||||
impl AdditionalPropertiesWithPatternsValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
patterns: PatternedValidators,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(AdditionalPropertiesWithPatternsValidator {
|
||||
validators: compile_validators(schema, context)?,
|
||||
patterns,
|
||||
|
@ -600,7 +603,7 @@ pub(crate) struct AdditionalPropertiesWithPatternsFalseValidator {
|
|||
}
|
||||
impl AdditionalPropertiesWithPatternsFalseValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(patterns: PatternedValidators) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(patterns: PatternedValidators) -> CompilationResult<'a> {
|
||||
Ok(Box::new(AdditionalPropertiesWithPatternsFalseValidator {
|
||||
patterns,
|
||||
}))
|
||||
|
@ -694,12 +697,12 @@ pub(crate) struct AdditionalPropertiesWithPatternsNotEmptyValidator<M: Propertie
|
|||
}
|
||||
impl AdditionalPropertiesWithPatternsNotEmptyValidator<SmallValidatorsMap> {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
map: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
map: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
patterns: PatternedValidators,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(
|
||||
AdditionalPropertiesWithPatternsNotEmptyValidator {
|
||||
validators: compile_validators(schema, context)?,
|
||||
|
@ -711,12 +714,12 @@ impl AdditionalPropertiesWithPatternsNotEmptyValidator<SmallValidatorsMap> {
|
|||
}
|
||||
impl AdditionalPropertiesWithPatternsNotEmptyValidator<BigValidatorsMap> {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
map: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
map: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
patterns: PatternedValidators,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(
|
||||
AdditionalPropertiesWithPatternsNotEmptyValidator {
|
||||
validators: compile_validators(schema, context)?,
|
||||
|
@ -851,11 +854,11 @@ pub(crate) struct AdditionalPropertiesWithPatternsNotEmptyFalseValidator<M: Prop
|
|||
}
|
||||
impl AdditionalPropertiesWithPatternsNotEmptyFalseValidator<SmallValidatorsMap> {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
map: &Map<String, Value>,
|
||||
pub(crate) fn compile<'a>(
|
||||
map: &'a Map<String, Value>,
|
||||
patterns: PatternedValidators,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(
|
||||
AdditionalPropertiesWithPatternsNotEmptyFalseValidator::<SmallValidatorsMap> {
|
||||
properties: compile_small_map(map, context)?,
|
||||
|
@ -866,11 +869,11 @@ impl AdditionalPropertiesWithPatternsNotEmptyFalseValidator<SmallValidatorsMap>
|
|||
}
|
||||
impl AdditionalPropertiesWithPatternsNotEmptyFalseValidator<BigValidatorsMap> {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
map: &Map<String, Value>,
|
||||
pub(crate) fn compile<'a>(
|
||||
map: &'a Map<String, Value>,
|
||||
patterns: PatternedValidators,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(
|
||||
AdditionalPropertiesWithPatternsNotEmptyFalseValidator {
|
||||
properties: compile_big_map(map, context)?,
|
||||
|
@ -967,11 +970,11 @@ impl<M: PropertiesValidatorsMap> ToString
|
|||
}
|
||||
}
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
parent: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
parent: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
let properties = parent.get("properties");
|
||||
if let Some(patterns) = parent.get("patternProperties") {
|
||||
if let Value::Object(obj) = patterns {
|
||||
|
@ -1012,10 +1015,10 @@ pub(crate) fn compile(
|
|||
}
|
||||
}
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::null_schema()))
|
||||
}
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::null_schema()))
|
||||
}
|
||||
} else {
|
||||
match schema {
|
||||
|
@ -1049,20 +1052,20 @@ pub(crate) fn compile(
|
|||
|
||||
/// Create a vector of pattern-validators pairs.
|
||||
#[inline]
|
||||
fn compile_patterns(
|
||||
obj: &Map<String, Value>,
|
||||
fn compile_patterns<'a>(
|
||||
obj: &'a Map<String, Value>,
|
||||
context: &CompilationContext,
|
||||
) -> Result<PatternedValidators, CompilationError> {
|
||||
) -> Result<PatternedValidators, ValidationError<'a>> {
|
||||
let mut compiled_patterns = Vec::with_capacity(obj.len());
|
||||
for (pattern, subschema) in obj {
|
||||
if let Ok(compiled_pattern) = Regex::new(pattern) {
|
||||
if let Ok(validators) = compile_validators(subschema, context) {
|
||||
compiled_patterns.push((compiled_pattern, validators));
|
||||
} else {
|
||||
return Err(CompilationError::SchemaError);
|
||||
return Err(ValidationError::schema(subschema));
|
||||
}
|
||||
} else {
|
||||
return Err(CompilationError::SchemaError);
|
||||
return Err(ValidationError::schema(subschema));
|
||||
}
|
||||
}
|
||||
Ok(compiled_patterns)
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
use crate::{
|
||||
compilation::{compile_validators, context::CompilationContext, JSONSchema},
|
||||
error::{CompilationError, ErrorIterator},
|
||||
keywords::{format_validators, format_vec_of_validators, CompilationResult, Validators},
|
||||
error::{ErrorIterator, ValidationError},
|
||||
keywords::{format_validators, format_vec_of_validators, Validators},
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
};
|
||||
use serde_json::{Map, Value};
|
||||
|
||||
use super::CompilationResult;
|
||||
|
||||
pub(crate) struct AllOfValidator {
|
||||
schemas: Vec<Validators>,
|
||||
}
|
||||
|
||||
impl AllOfValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(items: &[Value], context: &CompilationContext) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(
|
||||
items: &'a [Value],
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult<'a> {
|
||||
let mut schemas = Vec::with_capacity(items.len());
|
||||
for item in items {
|
||||
let validators = compile_validators(item, context)?;
|
||||
|
@ -62,7 +67,10 @@ pub(crate) struct SingleValueAllOfValidator {
|
|||
|
||||
impl SingleValueAllOfValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(schema: &Value, context: &CompilationContext) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult<'a> {
|
||||
let validators = compile_validators(schema, context)?;
|
||||
Ok(Box::new(SingleValueAllOfValidator { validators }))
|
||||
}
|
||||
|
@ -96,11 +104,11 @@ impl ToString for SingleValueAllOfValidator {
|
|||
}
|
||||
}
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
if let Value::Array(items) = schema {
|
||||
if items.len() == 1 {
|
||||
let value = items.iter().next().expect("Vec is not empty");
|
||||
|
@ -109,6 +117,6 @@ pub(crate) fn compile(
|
|||
Some(AllOfValidator::compile(items, context))
|
||||
}
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::schema(schema)))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
use crate::{
|
||||
compilation::{compile_validators, context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
keywords::{format_vec_of_validators, CompilationResult, Validators},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::{format_vec_of_validators, Validators},
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
};
|
||||
use serde_json::{Map, Value};
|
||||
|
||||
use super::CompilationResult;
|
||||
|
||||
pub(crate) struct AnyOfValidator {
|
||||
schemas: Vec<Validators>,
|
||||
}
|
||||
|
||||
impl AnyOfValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(schema: &Value, context: &CompilationContext) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult<'a> {
|
||||
if let Value::Array(items) = schema {
|
||||
let mut schemas = Vec::with_capacity(items.len());
|
||||
for item in items {
|
||||
|
@ -22,7 +27,7 @@ impl AnyOfValidator {
|
|||
}
|
||||
Ok(Box::new(AnyOfValidator { schemas }))
|
||||
} else {
|
||||
Err(CompilationError::SchemaError)
|
||||
Err(ValidationError::schema(schema))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,10 +65,10 @@ impl ToString for AnyOfValidator {
|
|||
}
|
||||
}
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
Some(AnyOfValidator::compile(schema, context))
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use serde_json::Value;
|
|||
pub(crate) struct FalseValidator {}
|
||||
impl FalseValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new(FalseValidator {}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ struct ConstBooleanValidator {
|
|||
}
|
||||
impl ConstBooleanValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(value: bool) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(value: bool) -> CompilationResult<'a> {
|
||||
Ok(Box::new(ConstBooleanValidator { value }))
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ impl ToString for ConstBooleanValidator {
|
|||
struct ConstNullValidator {}
|
||||
impl ConstNullValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new(ConstNullValidator {}))
|
||||
}
|
||||
}
|
||||
|
@ -291,11 +291,11 @@ impl ToString for ConstStringValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
match schema {
|
||||
Value::Array(items) => Some(ConstArrayValidator::compile(items)),
|
||||
Value::Bool(item) => Some(ConstBooleanValidator::compile(*item)),
|
||||
|
|
|
@ -13,7 +13,10 @@ pub(crate) struct ContainsValidator {
|
|||
|
||||
impl ContainsValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(schema: &Value, context: &CompilationContext) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(ContainsValidator {
|
||||
validators: compile_validators(schema, context)?,
|
||||
}))
|
||||
|
@ -68,10 +71,10 @@ impl ToString for ContainsValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
Some(ContainsValidator::compile(schema, context))
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::{
|
|||
compilation::{context::CompilationContext, JSONSchema},
|
||||
content_encoding::{ContentEncodingCheckType, ContentEncodingConverterType},
|
||||
content_media_type::ContentMediaTypeCheckType,
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -127,12 +127,12 @@ pub(crate) struct ContentMediaTypeAndEncodingValidator {
|
|||
|
||||
impl ContentMediaTypeAndEncodingValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
media_type: &str,
|
||||
encoding: &str,
|
||||
pub(crate) fn compile<'a>(
|
||||
media_type: &'a str,
|
||||
encoding: &'a str,
|
||||
func: ContentMediaTypeCheckType,
|
||||
converter: ContentEncodingConverterType,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(ContentMediaTypeAndEncodingValidator {
|
||||
media_type: media_type.to_string(),
|
||||
encoding: encoding.to_string(),
|
||||
|
@ -197,11 +197,11 @@ impl ToString for ContentMediaTypeAndEncodingValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile_media_type(
|
||||
schema: &Map<String, Value>,
|
||||
subschema: &Value,
|
||||
pub(crate) fn compile_media_type<'a>(
|
||||
schema: &'a Map<String, Value>,
|
||||
subschema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
match subschema {
|
||||
Value::String(media_type) => {
|
||||
let func = match context.config.content_media_type_check(media_type.as_str()) {
|
||||
|
@ -225,22 +225,22 @@ pub(crate) fn compile_media_type(
|
|||
converter,
|
||||
))
|
||||
}
|
||||
_ => Some(Err(CompilationError::SchemaError)),
|
||||
_ => Some(Err(ValidationError::schema(subschema))),
|
||||
}
|
||||
} else {
|
||||
Some(ContentMediaTypeValidator::compile(media_type, func))
|
||||
}
|
||||
}
|
||||
_ => Some(Err(CompilationError::SchemaError)),
|
||||
_ => Some(Err(ValidationError::schema(subschema))),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile_content_encoding(
|
||||
schema: &Map<String, Value>,
|
||||
subschema: &Value,
|
||||
pub(crate) fn compile_content_encoding<'a>(
|
||||
schema: &'a Map<String, Value>,
|
||||
subschema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
// Performed during media type validation
|
||||
if schema.get("contentMediaType").is_some() {
|
||||
// TODO. what if media type is not supported?
|
||||
|
@ -257,6 +257,6 @@ pub(crate) fn compile_content_encoding(
|
|||
};
|
||||
Some(ContentEncodingValidator::compile(content_encoding, func))
|
||||
}
|
||||
_ => Some(Err(CompilationError::SchemaError)),
|
||||
_ => Some(Err(ValidationError::schema(subschema))),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{compile_validators, context::CompilationContext, JSONSchema},
|
||||
error::{no_error, CompilationError, ErrorIterator},
|
||||
error::{no_error, ErrorIterator, ValidationError},
|
||||
keywords::{format_key_value_validators, required, CompilationResult, Validators},
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -13,7 +13,10 @@ pub(crate) struct DependenciesValidator {
|
|||
|
||||
impl DependenciesValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(schema: &Value, context: &CompilationContext) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult<'a> {
|
||||
if let Value::Object(map) = schema {
|
||||
let mut dependencies = Vec::with_capacity(map.len());
|
||||
for (key, subschema) in map {
|
||||
|
@ -28,7 +31,7 @@ impl DependenciesValidator {
|
|||
}
|
||||
Ok(Box::new(DependenciesValidator { dependencies }))
|
||||
} else {
|
||||
Err(CompilationError::SchemaError)
|
||||
Err(ValidationError::schema(schema))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,10 +87,10 @@ impl ToString for DependenciesValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
Some(DependenciesValidator::compile(schema, context))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::{helpers, CompilationResult},
|
||||
paths::InstancePath,
|
||||
primitive_type::{PrimitiveType, PrimitiveTypesBitMap},
|
||||
|
@ -18,7 +18,7 @@ pub(crate) struct EnumValidator {
|
|||
|
||||
impl EnumValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(schema: &Value, items: &[Value]) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(schema: &'a Value, items: &'a [Value]) -> CompilationResult<'a> {
|
||||
let mut types = PrimitiveTypesBitMap::new();
|
||||
for item in items.iter() {
|
||||
types |= PrimitiveType::from(item);
|
||||
|
@ -82,7 +82,7 @@ pub(crate) struct SingleValueEnumValidator {
|
|||
|
||||
impl SingleValueEnumValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(schema: &Value, value: &Value) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(schema: &'a Value, value: &'a Value) -> CompilationResult<'a> {
|
||||
Ok(Box::new(SingleValueEnumValidator {
|
||||
options: schema.clone(),
|
||||
value: value.clone(),
|
||||
|
@ -120,11 +120,11 @@ impl ToString for SingleValueEnumValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
if let Value::Array(items) = schema {
|
||||
if items.len() == 1 {
|
||||
let value = items.iter().next().expect("Vec is not empty");
|
||||
|
@ -133,6 +133,6 @@ pub(crate) fn compile(
|
|||
Some(EnumValidator::compile(schema, items))
|
||||
}
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::schema(schema)))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -104,11 +104,11 @@ impl ToString for ExclusiveMaximumF64Validator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
if let Value::Number(limit) = schema {
|
||||
if let Some(limit) = limit.as_u64() {
|
||||
Some(Ok(Box::new(ExclusiveMaximumU64Validator { limit })))
|
||||
|
@ -119,7 +119,7 @@ pub(crate) fn compile(
|
|||
Some(Ok(Box::new(ExclusiveMaximumF64Validator { limit })))
|
||||
}
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::schema(schema)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -102,11 +102,11 @@ impl ToString for ExclusiveMinimumF64Validator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
if let Value::Number(limit) = schema {
|
||||
if let Some(limit) = limit.as_u64() {
|
||||
Some(Ok(Box::new(ExclusiveMinimumU64Validator { limit })))
|
||||
|
@ -117,7 +117,7 @@ pub(crate) fn compile(
|
|||
Some(Ok(Box::new(ExclusiveMinimumF64Validator { limit })))
|
||||
}
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::schema(schema)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Validator for `format` keyword.
|
||||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::{pattern, CompilationResult},
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -38,7 +38,7 @@ macro_rules! format_validator {
|
|||
($validator:ident, $format_name:tt) => {
|
||||
struct $validator {}
|
||||
impl $validator {
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new($validator {}))
|
||||
}
|
||||
}
|
||||
|
@ -325,11 +325,11 @@ impl Validate for URITemplateValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
if let Value::String(format) = schema {
|
||||
let draft_version = context.config.draft();
|
||||
match format.as_str() {
|
||||
|
@ -365,7 +365,7 @@ pub(crate) fn compile(
|
|||
_ => None,
|
||||
}
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::schema(schema)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,11 +14,11 @@ pub(crate) struct IfThenValidator {
|
|||
|
||||
impl IfThenValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
schema: &Value,
|
||||
then_schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
then_schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(IfThenValidator {
|
||||
schema: compile_validators(schema, context)?,
|
||||
then_schema: compile_validators(then_schema, context)?,
|
||||
|
@ -85,7 +85,7 @@ impl IfElseValidator {
|
|||
schema: &'a Value,
|
||||
else_schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(IfElseValidator {
|
||||
schema: compile_validators(schema, context)?,
|
||||
else_schema: compile_validators(else_schema, context)?,
|
||||
|
@ -149,12 +149,12 @@ pub(crate) struct IfThenElseValidator {
|
|||
|
||||
impl IfThenElseValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
schema: &Value,
|
||||
then_schema: &Value,
|
||||
else_schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
then_schema: &'a Value,
|
||||
else_schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(IfThenElseValidator {
|
||||
schema: compile_validators(schema, context)?,
|
||||
then_schema: compile_validators(then_schema, context)?,
|
||||
|
@ -220,11 +220,11 @@ impl ToString for IfThenElseValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
parent: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
parent: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
let then = parent.get("then");
|
||||
let else_ = parent.get("else");
|
||||
match (then, else_) {
|
||||
|
|
|
@ -12,7 +12,10 @@ pub(crate) struct ItemsArrayValidator {
|
|||
}
|
||||
impl ItemsArrayValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(schemas: &[Value], context: &CompilationContext) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(
|
||||
schemas: &'a [Value],
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult<'a> {
|
||||
let mut items = Vec::with_capacity(schemas.len());
|
||||
for item in schemas {
|
||||
let validators = compile_validators(item, context)?;
|
||||
|
@ -72,7 +75,10 @@ pub(crate) struct ItemsObjectValidator {
|
|||
}
|
||||
impl ItemsObjectValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(schema: &Value, context: &CompilationContext) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult<'a> {
|
||||
let validators = compile_validators(schema, context)?;
|
||||
Ok(Box::new(ItemsObjectValidator { validators }))
|
||||
}
|
||||
|
@ -120,11 +126,11 @@ impl ToString for ItemsObjectValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
match schema {
|
||||
Value::Array(items) => Some(ItemsArrayValidator::compile(items, context)),
|
||||
Value::Object(_) => Some(ItemsObjectValidator::compile(schema, context)),
|
||||
|
|
|
@ -5,11 +5,11 @@ use crate::{
|
|||
use serde_json::{Map, Value};
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
parent: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
parent: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
if let Some(Value::Bool(true)) = parent.get("exclusiveMaximum") {
|
||||
exclusive_maximum::compile(parent, schema, context)
|
||||
} else {
|
||||
|
|
|
@ -5,11 +5,11 @@ use crate::{
|
|||
use serde_json::{Map, Value};
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
parent: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
parent: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
if let Some(Value::Bool(true)) = parent.get("exclusiveMinimum") {
|
||||
exclusive_minimum::compile(parent, schema, context)
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::{type_, CompilationResult},
|
||||
paths::InstancePath,
|
||||
primitive_type::{PrimitiveType, PrimitiveTypesBitMap},
|
||||
|
@ -23,10 +23,10 @@ impl MultipleTypesValidator {
|
|||
if let Ok(primitive_type) = PrimitiveType::try_from(string.as_str()) {
|
||||
types |= primitive_type;
|
||||
} else {
|
||||
return Err(CompilationError::SchemaError);
|
||||
return Err(ValidationError::schema(item));
|
||||
}
|
||||
}
|
||||
_ => return Err(CompilationError::SchemaError),
|
||||
_ => return Err(ValidationError::schema(item)),
|
||||
}
|
||||
}
|
||||
Ok(Box::new(MultipleTypesValidator { types }))
|
||||
|
@ -82,7 +82,7 @@ pub(crate) struct IntegerTypeValidator {}
|
|||
|
||||
impl IntegerTypeValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new(IntegerTypeValidator {}))
|
||||
}
|
||||
}
|
||||
|
@ -125,11 +125,11 @@ fn is_integer(num: &Number) -> bool {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
match schema {
|
||||
Value::String(item) => compile_single_type(item.as_str()),
|
||||
Value::Array(items) => {
|
||||
|
@ -137,17 +137,17 @@ pub(crate) fn compile(
|
|||
if let Some(Value::String(item)) = items.iter().next() {
|
||||
compile_single_type(item.as_str())
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::schema(schema)))
|
||||
}
|
||||
} else {
|
||||
Some(MultipleTypesValidator::compile(items))
|
||||
}
|
||||
}
|
||||
_ => Some(Err(CompilationError::SchemaError)),
|
||||
_ => Some(Err(ValidationError::schema(schema))),
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_single_type(item: &str) -> Option<CompilationResult> {
|
||||
fn compile_single_type<'a>(item: &str) -> Option<CompilationResult<'a>> {
|
||||
match PrimitiveType::try_from(item) {
|
||||
Ok(PrimitiveType::Array) => Some(type_::ArrayTypeValidator::compile()),
|
||||
Ok(PrimitiveType::Boolean) => Some(type_::BooleanTypeValidator::compile()),
|
||||
|
@ -156,6 +156,6 @@ fn compile_single_type(item: &str) -> Option<CompilationResult> {
|
|||
Ok(PrimitiveType::Number) => Some(type_::NumberTypeValidator::compile()),
|
||||
Ok(PrimitiveType::Object) => Some(type_::ObjectTypeValidator::compile()),
|
||||
Ok(PrimitiveType::String) => Some(type_::StringTypeValidator::compile()),
|
||||
Err(()) => Some(Err(CompilationError::SchemaError)),
|
||||
Err(()) => Some(Err(ValidationError::null_schema())),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -17,7 +17,7 @@ impl MaxItemsValidator {
|
|||
if let Some(limit) = schema.as_u64() {
|
||||
Ok(Box::new(MaxItemsValidator { limit }))
|
||||
} else {
|
||||
Err(CompilationError::SchemaError)
|
||||
Err(ValidationError::schema(schema))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,10 +58,10 @@ impl ToString for MaxItemsValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
Some(MaxItemsValidator::compile(schema))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -17,7 +17,7 @@ impl MaxLengthValidator {
|
|||
if let Some(limit) = schema.as_u64() {
|
||||
Ok(Box::new(MaxLengthValidator { limit }))
|
||||
} else {
|
||||
Err(CompilationError::SchemaError)
|
||||
Err(ValidationError::schema(schema))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,10 +58,10 @@ impl ToString for MaxLengthValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
Some(MaxLengthValidator::compile(schema))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -17,7 +17,7 @@ impl MaxPropertiesValidator {
|
|||
if let Some(limit) = schema.as_u64() {
|
||||
Ok(Box::new(MaxPropertiesValidator { limit }))
|
||||
} else {
|
||||
Err(CompilationError::SchemaError)
|
||||
Err(ValidationError::schema(schema))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,10 +58,10 @@ impl ToString for MaxPropertiesValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
Some(MaxPropertiesValidator::compile(schema))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -102,11 +102,11 @@ impl ToString for MaximumF64Validator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
if let Value::Number(limit) = schema {
|
||||
if let Some(limit) = limit.as_u64() {
|
||||
Some(Ok(Box::new(MaximumU64Validator { limit })))
|
||||
|
@ -117,7 +117,7 @@ pub(crate) fn compile(
|
|||
Some(Ok(Box::new(MaximumF64Validator { limit })))
|
||||
}
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::schema(schema)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -17,7 +17,7 @@ impl MinItemsValidator {
|
|||
if let Some(limit) = schema.as_u64() {
|
||||
Ok(Box::new(MinItemsValidator { limit }))
|
||||
} else {
|
||||
Err(CompilationError::SchemaError)
|
||||
Err(ValidationError::schema(schema))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,10 +58,10 @@ impl ToString for MinItemsValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
Some(MinItemsValidator::compile(schema))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -17,7 +17,7 @@ impl MinLengthValidator {
|
|||
if let Some(limit) = schema.as_u64() {
|
||||
Ok(Box::new(MinLengthValidator { limit }))
|
||||
} else {
|
||||
Err(CompilationError::SchemaError)
|
||||
Err(ValidationError::schema(schema))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,10 +58,10 @@ impl ToString for MinLengthValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
Some(MinLengthValidator::compile(schema))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -17,7 +17,7 @@ impl MinPropertiesValidator {
|
|||
if let Some(limit) = schema.as_u64() {
|
||||
Ok(Box::new(MinPropertiesValidator { limit }))
|
||||
} else {
|
||||
Err(CompilationError::SchemaError)
|
||||
Err(ValidationError::schema(schema))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,10 +58,10 @@ impl ToString for MinPropertiesValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
Some(MinPropertiesValidator::compile(schema))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -102,11 +102,11 @@ impl ToString for MinimumF64Validator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
if let Value::Number(limit) = schema {
|
||||
if let Some(limit) = limit.as_u64() {
|
||||
Some(Ok(Box::new(MinimumU64Validator { limit })))
|
||||
|
@ -117,7 +117,7 @@ pub(crate) fn compile(
|
|||
Some(Ok(Box::new(MinimumF64Validator { limit })))
|
||||
}
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::schema(schema)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ pub(crate) mod type_;
|
|||
pub(crate) mod unique_items;
|
||||
use crate::{error, validator::Validate};
|
||||
|
||||
pub(crate) type CompilationResult = Result<BoxedValidator, error::CompilationError>;
|
||||
pub(crate) type CompilationResult<'a> = Result<BoxedValidator, error::ValidationError<'a>>;
|
||||
pub(crate) type BoxedValidator = Box<dyn Validate + Send + Sync>;
|
||||
pub(crate) type Validators = Vec<BoxedValidator>;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -15,7 +15,7 @@ pub(crate) struct MultipleOfFloatValidator {
|
|||
|
||||
impl MultipleOfFloatValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(multiple_of: f64) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(multiple_of: f64) -> CompilationResult<'a> {
|
||||
Ok(Box::new(MultipleOfFloatValidator { multiple_of }))
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ pub(crate) struct MultipleOfIntegerValidator {
|
|||
|
||||
impl MultipleOfIntegerValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(multiple_of: f64) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(multiple_of: f64) -> CompilationResult<'a> {
|
||||
Ok(Box::new(MultipleOfIntegerValidator { multiple_of }))
|
||||
}
|
||||
}
|
||||
|
@ -112,11 +112,11 @@ impl ToString for MultipleOfIntegerValidator {
|
|||
}
|
||||
}
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
if let Value::Number(multiple_of) = schema {
|
||||
let multiple_of = multiple_of.as_f64().expect("Always valid");
|
||||
if multiple_of.fract() == 0. {
|
||||
|
@ -125,6 +125,6 @@ pub(crate) fn compile(
|
|||
Some(MultipleOfFloatValidator::compile(multiple_of))
|
||||
}
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::schema(schema)))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,10 @@ pub(crate) struct NotValidator {
|
|||
|
||||
impl NotValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(schema: &Value, context: &CompilationContext) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(NotValidator {
|
||||
original: schema.clone(),
|
||||
validators: compile_validators(schema, context)?,
|
||||
|
@ -56,10 +59,10 @@ impl ToString for NotValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
Some(NotValidator::compile(schema, context))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{compile_validators, context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::{format_vec_of_validators, CompilationResult, Validators},
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -13,7 +13,10 @@ pub(crate) struct OneOfValidator {
|
|||
|
||||
impl OneOfValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(schema: &Value, context: &CompilationContext) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult<'a> {
|
||||
if let Value::Array(items) = schema {
|
||||
let mut schemas = Vec::with_capacity(items.len());
|
||||
for item in items {
|
||||
|
@ -21,7 +24,7 @@ impl OneOfValidator {
|
|||
}
|
||||
Ok(Box::new(OneOfValidator { schemas }))
|
||||
} else {
|
||||
Err(CompilationError::SchemaError)
|
||||
Err(ValidationError::schema(schema))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,10 +95,10 @@ impl ToString for OneOfValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
Some(OneOfValidator::compile(schema, context))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -24,13 +24,16 @@ impl PatternValidator {
|
|||
pub(crate) fn compile(pattern: &Value) -> CompilationResult {
|
||||
match pattern {
|
||||
Value::String(item) => {
|
||||
let pattern = convert_regex(item)?;
|
||||
let pattern = match convert_regex(item) {
|
||||
Ok(r) => r,
|
||||
Err(_) => return Err(ValidationError::schema(pattern)),
|
||||
};
|
||||
Ok(Box::new(PatternValidator {
|
||||
original: item.clone(),
|
||||
pattern,
|
||||
}))
|
||||
}
|
||||
_ => Err(CompilationError::SchemaError),
|
||||
_ => Err(ValidationError::schema(pattern)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,11 +140,11 @@ fn replace_control_group(captures: ®ex::Captures) -> String {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
Some(PatternValidator::compile(schema))
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{compile_validators, context::CompilationContext, JSONSchema},
|
||||
error::{no_error, CompilationError, ErrorIterator},
|
||||
error::{no_error, ErrorIterator, ValidationError},
|
||||
keywords::{format_validators, CompilationResult, Validators},
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -14,14 +14,17 @@ pub(crate) struct PatternPropertiesValidator {
|
|||
|
||||
impl PatternPropertiesValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
map: &Map<String, Value>,
|
||||
pub(crate) fn compile<'a>(
|
||||
map: &'a Map<String, Value>,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
let mut patterns = Vec::with_capacity(map.len());
|
||||
for (pattern, subschema) in map {
|
||||
patterns.push((
|
||||
Regex::new(pattern)?,
|
||||
match Regex::new(pattern) {
|
||||
Ok(r) => r,
|
||||
Err(_) => return Err(ValidationError::schema(subschema)),
|
||||
},
|
||||
compile_validators(subschema, context)?,
|
||||
));
|
||||
}
|
||||
|
@ -94,13 +97,16 @@ pub(crate) struct SingleValuePatternPropertiesValidator {
|
|||
|
||||
impl SingleValuePatternPropertiesValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
pattern: &str,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
pattern: &'a str,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult {
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(SingleValuePatternPropertiesValidator {
|
||||
pattern: Regex::new(pattern)?,
|
||||
pattern: match Regex::new(pattern) {
|
||||
Ok(r) => r,
|
||||
Err(_) => return Err(ValidationError::schema(schema)),
|
||||
},
|
||||
validators: compile_validators(schema, context)?,
|
||||
}))
|
||||
}
|
||||
|
@ -156,11 +162,11 @@ impl ToString for SingleValuePatternPropertiesValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
parent: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
parent: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
match parent.get("additionalProperties") {
|
||||
// This type of `additionalProperties` validator handles `patternProperties` logic
|
||||
Some(Value::Bool(false)) | Some(Value::Object(_)) => None,
|
||||
|
@ -175,7 +181,7 @@ pub(crate) fn compile(
|
|||
Some(PatternPropertiesValidator::compile(map, context))
|
||||
}
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::schema(schema)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{compile_validators, context::CompilationContext, JSONSchema},
|
||||
error::{no_error, CompilationError, ErrorIterator},
|
||||
error::{no_error, ErrorIterator, ValidationError},
|
||||
keywords::{format_key_value_validators, CompilationResult, Validators},
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -13,7 +13,10 @@ pub(crate) struct PropertiesValidator {
|
|||
|
||||
impl PropertiesValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(schema: &Value, context: &CompilationContext) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult<'a> {
|
||||
match schema {
|
||||
Value::Object(map) => {
|
||||
let mut properties = Vec::with_capacity(map.len());
|
||||
|
@ -22,7 +25,7 @@ impl PropertiesValidator {
|
|||
}
|
||||
Ok(Box::new(PropertiesValidator { properties }))
|
||||
}
|
||||
_ => Err(CompilationError::SchemaError),
|
||||
_ => Err(ValidationError::schema(schema)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,11 +83,11 @@ impl ToString for PropertiesValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
parent: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
parent: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
match parent.get("additionalProperties") {
|
||||
// This type of `additionalProperties` validator handles `properties` logic
|
||||
Some(Value::Bool(false)) | Some(Value::Object(_)) => None,
|
||||
|
|
|
@ -14,7 +14,10 @@ pub(crate) struct PropertyNamesObjectValidator {
|
|||
|
||||
impl PropertyNamesObjectValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(schema: &Value, context: &CompilationContext) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult<'a> {
|
||||
Ok(Box::new(PropertyNamesObjectValidator {
|
||||
validators: compile_validators(schema, context)?,
|
||||
}))
|
||||
|
@ -78,7 +81,7 @@ pub(crate) struct PropertyNamesBooleanValidator {}
|
|||
|
||||
impl PropertyNamesBooleanValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new(PropertyNamesBooleanValidator {}))
|
||||
}
|
||||
}
|
||||
|
@ -117,11 +120,11 @@ impl ToString for PropertyNamesBooleanValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
match schema {
|
||||
Value::Object(_) => Some(PropertyNamesObjectValidator::compile(schema, context)),
|
||||
Value::Bool(false) => Some(PropertyNamesBooleanValidator::compile()),
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::{
|
|||
compilation::{compile_validators, context::CompilationContext, JSONSchema},
|
||||
error::{error, ErrorIterator},
|
||||
keywords::{CompilationResult, Validators},
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
};
|
||||
use parking_lot::RwLock;
|
||||
|
@ -9,8 +10,6 @@ use serde_json::Value;
|
|||
use std::borrow::Cow;
|
||||
use url::Url;
|
||||
|
||||
use crate::paths::InstancePath;
|
||||
|
||||
pub(crate) struct RefValidator {
|
||||
reference: Url,
|
||||
/// Precomputed validators.
|
||||
|
@ -23,7 +22,10 @@ pub(crate) struct RefValidator {
|
|||
|
||||
impl RefValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile(reference: &str, context: &CompilationContext) -> CompilationResult {
|
||||
pub(crate) fn compile<'a>(
|
||||
reference: &str,
|
||||
context: &CompilationContext,
|
||||
) -> CompilationResult<'a> {
|
||||
let reference = context.build_url(reference)?;
|
||||
Ok(Box::new(RefValidator {
|
||||
reference,
|
||||
|
@ -92,7 +94,7 @@ impl Validate for RefValidator {
|
|||
*self.validators.write() = Some(validators);
|
||||
result
|
||||
}
|
||||
Err(err) => error(err.into()),
|
||||
Err(err) => error(err.into_owned()),
|
||||
}
|
||||
}
|
||||
Err(err) => error(err),
|
||||
|
@ -107,10 +109,10 @@ impl ToString for RefValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Value,
|
||||
reference: &str,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Value,
|
||||
reference: &'a str,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
Some(RefValidator::compile(reference, context))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
paths::InstancePath,
|
||||
validator::Validate,
|
||||
|
@ -18,7 +18,7 @@ impl RequiredValidator {
|
|||
for item in items {
|
||||
match item {
|
||||
Value::String(string) => required.push(string.clone()),
|
||||
_ => return Err(CompilationError::SchemaError),
|
||||
_ => return Err(ValidationError::schema(item)),
|
||||
}
|
||||
}
|
||||
Ok(Box::new(RequiredValidator { required }))
|
||||
|
@ -115,11 +115,11 @@ impl ToString for SingleItemRequiredValidator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
// IMPORTANT: If this function will ever return `None`, adjust `dependencies.rs` accordingly
|
||||
match schema {
|
||||
Value::Array(items) => {
|
||||
|
@ -127,12 +127,12 @@ pub(crate) fn compile(
|
|||
if let Some(Value::String(item)) = items.iter().next() {
|
||||
Some(SingleItemRequiredValidator::compile(item))
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::schema(schema)))
|
||||
}
|
||||
} else {
|
||||
Some(RequiredValidator::compile(items))
|
||||
}
|
||||
}
|
||||
_ => Some(Err(CompilationError::SchemaError)),
|
||||
_ => Some(Err(ValidationError::schema(schema))),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
compilation::{context::CompilationContext, JSONSchema},
|
||||
error::{error, no_error, CompilationError, ErrorIterator, ValidationError},
|
||||
error::{error, no_error, ErrorIterator, ValidationError},
|
||||
keywords::CompilationResult,
|
||||
primitive_type::{PrimitiveType, PrimitiveTypesBitMap},
|
||||
validator::Validate,
|
||||
|
@ -24,10 +24,10 @@ impl MultipleTypesValidator {
|
|||
if let Ok(primitive_type) = PrimitiveType::try_from(string.as_str()) {
|
||||
types |= primitive_type;
|
||||
} else {
|
||||
return Err(CompilationError::SchemaError);
|
||||
return Err(ValidationError::schema(item));
|
||||
}
|
||||
}
|
||||
_ => return Err(CompilationError::SchemaError),
|
||||
_ => return Err(ValidationError::schema(item)),
|
||||
}
|
||||
}
|
||||
Ok(Box::new(MultipleTypesValidator { types }))
|
||||
|
@ -83,7 +83,7 @@ pub(crate) struct NullTypeValidator {}
|
|||
|
||||
impl NullTypeValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new(NullTypeValidator {}))
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ pub(crate) struct BooleanTypeValidator {}
|
|||
|
||||
impl BooleanTypeValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new(BooleanTypeValidator {}))
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ pub(crate) struct StringTypeValidator {}
|
|||
|
||||
impl StringTypeValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new(StringTypeValidator {}))
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ pub(crate) struct ArrayTypeValidator {}
|
|||
|
||||
impl ArrayTypeValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new(ArrayTypeValidator {}))
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ pub(crate) struct ObjectTypeValidator {}
|
|||
|
||||
impl ObjectTypeValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new(ObjectTypeValidator {}))
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ pub(crate) struct NumberTypeValidator {}
|
|||
|
||||
impl NumberTypeValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new(NumberTypeValidator {}))
|
||||
}
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ pub(crate) struct IntegerTypeValidator {}
|
|||
|
||||
impl IntegerTypeValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new(IntegerTypeValidator {}))
|
||||
}
|
||||
}
|
||||
|
@ -346,11 +346,11 @@ fn is_integer(num: &Number) -> bool {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
match schema {
|
||||
Value::String(item) => compile_single_type(item.as_str()),
|
||||
Value::Array(items) => {
|
||||
|
@ -358,13 +358,13 @@ pub(crate) fn compile(
|
|||
if let Some(Value::String(item)) = items.iter().next() {
|
||||
compile_single_type(item.as_str())
|
||||
} else {
|
||||
Some(Err(CompilationError::SchemaError))
|
||||
Some(Err(ValidationError::schema(schema)))
|
||||
}
|
||||
} else {
|
||||
Some(MultipleTypesValidator::compile(items))
|
||||
}
|
||||
}
|
||||
_ => Some(Err(CompilationError::SchemaError)),
|
||||
_ => Some(Err(ValidationError::schema(schema))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,6 +377,6 @@ fn compile_single_type(item: &str) -> Option<CompilationResult> {
|
|||
Ok(PrimitiveType::Number) => Some(NumberTypeValidator::compile()),
|
||||
Ok(PrimitiveType::Object) => Some(ObjectTypeValidator::compile()),
|
||||
Ok(PrimitiveType::String) => Some(StringTypeValidator::compile()),
|
||||
Err(()) => Some(Err(CompilationError::SchemaError)),
|
||||
Err(()) => Some(Err(ValidationError::null_schema())),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ pub(crate) struct UniqueItemsValidator {}
|
|||
|
||||
impl UniqueItemsValidator {
|
||||
#[inline]
|
||||
pub(crate) fn compile() -> CompilationResult {
|
||||
pub(crate) fn compile<'a>() -> CompilationResult<'a> {
|
||||
Ok(Box::new(UniqueItemsValidator {}))
|
||||
}
|
||||
}
|
||||
|
@ -124,11 +124,11 @@ impl ToString for UniqueItemsValidator {
|
|||
}
|
||||
}
|
||||
#[inline]
|
||||
pub(crate) fn compile(
|
||||
_: &Map<String, Value>,
|
||||
schema: &Value,
|
||||
pub(crate) fn compile<'a>(
|
||||
_: &'a Map<String, Value>,
|
||||
schema: &'a Value,
|
||||
_: &CompilationContext,
|
||||
) -> Option<CompilationResult> {
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
if let Value::Bool(value) = schema {
|
||||
if *value {
|
||||
Some(UniqueItemsValidator::compile())
|
||||
|
|
|
@ -11,46 +11,43 @@
|
|||
//! A schema can be compiled with two main flavours:
|
||||
//! * using default configurations
|
||||
//! ```rust
|
||||
//! # use jsonschema::{CompilationError, Draft, JSONSchema};
|
||||
//! # use jsonschema::{Draft, JSONSchema};
|
||||
//! # use serde_json::json;
|
||||
//! # fn foo() -> Result<(), CompilationError> {
|
||||
//! # fn foo() {
|
||||
//! # let schema = json!({"maxLength": 5});
|
||||
//! let compiled_schema = JSONSchema::compile(&schema)?;
|
||||
//! # Ok(())
|
||||
//! let compiled_schema = JSONSchema::compile(&schema).expect("A valid schema");
|
||||
//! # }
|
||||
//! ```
|
||||
//! * using custom configurations (such as define a Draft version)
|
||||
//! ```rust
|
||||
//! # use jsonschema::{CompilationError, Draft, JSONSchema};
|
||||
//! # use jsonschema::{Draft, JSONSchema};
|
||||
//! # use serde_json::json;
|
||||
//! # fn foo() -> Result<(), CompilationError> {
|
||||
//! # fn foo() {
|
||||
//! # let schema = json!({"maxLength": 5});
|
||||
//! let compiled_schema = JSONSchema::options()
|
||||
//! .with_draft(Draft::Draft7)
|
||||
//! .compile(&schema)?;
|
||||
//! # Ok(())
|
||||
//! .compile(&schema)
|
||||
//! .expect("A valid schema");
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Example (CLI tool to highlight print errors)
|
||||
//! ```rust
|
||||
//! use jsonschema::{CompilationError, Draft, JSONSchema};
|
||||
//! use jsonschema::{Draft, JSONSchema};
|
||||
//! use serde_json::json;
|
||||
//!
|
||||
//! fn main() -> Result<(), CompilationError> {
|
||||
//! let schema = json!({"maxLength": 5});
|
||||
//! let instance = json!("foo");
|
||||
//! let compiled = JSONSchema::options()
|
||||
//! .with_draft(Draft::Draft7)
|
||||
//! .compile(&schema)?;
|
||||
//! let result = compiled.validate(&instance);
|
||||
//! if let Err(errors) = result {
|
||||
//! for error in errors {
|
||||
//! println!("Validation error: {}", error);
|
||||
//! println!("Instance path: {}", error.instance_path);
|
||||
//! }
|
||||
//! let schema = json!({"maxLength": 5});
|
||||
//! let instance = json!("foo");
|
||||
//! let compiled = JSONSchema::options()
|
||||
//! .with_draft(Draft::Draft7)
|
||||
//! .compile(&schema)
|
||||
//! .expect("A valid schema");
|
||||
//! let result = compiled.validate(&instance);
|
||||
//! if let Err(errors) = result {
|
||||
//! for error in errors {
|
||||
//! println!("Validation error: {}", error);
|
||||
//! println!("Instance path: {}", error.instance_path);
|
||||
//! }
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
//! Each error has an `instance_path` attribute that indicates the path to the erroneous part within the validated instance.
|
||||
|
@ -91,7 +88,7 @@ mod schemas;
|
|||
mod validator;
|
||||
|
||||
pub use compilation::{options::CompilationOptions, JSONSchema};
|
||||
pub use error::{CompilationError, ErrorIterator, ValidationError};
|
||||
pub use error::{ErrorIterator, ValidationError};
|
||||
pub use schemas::Draft;
|
||||
use serde_json::Value;
|
||||
|
||||
|
|
|
@ -48,25 +48,30 @@ fn validate_instances(instances: &[PathBuf], schema: PathBuf) -> BoxErrorResult<
|
|||
|
||||
let schema_json = fs::read_to_string(schema)?;
|
||||
let schema_json = serde_json::from_str(&schema_json)?;
|
||||
let schema = JSONSchema::compile(&schema_json)?;
|
||||
match JSONSchema::compile(&schema_json) {
|
||||
Ok(schema) => {
|
||||
for instance in instances {
|
||||
let instance_path_name = instance.to_str().unwrap();
|
||||
let instance_json = fs::read_to_string(&instance)?;
|
||||
let instance_json = serde_json::from_str(&instance_json)?;
|
||||
let validation = schema.validate(&instance_json);
|
||||
match validation {
|
||||
Ok(_) => println!("{} - VALID", instance_path_name),
|
||||
Err(errors) => {
|
||||
success = false;
|
||||
|
||||
for instance in instances {
|
||||
let instance_path_name = instance.to_str().unwrap();
|
||||
let instance_json = fs::read_to_string(&instance)?;
|
||||
let instance_json = serde_json::from_str(&instance_json)?;
|
||||
let validation = schema.validate(&instance_json);
|
||||
match validation {
|
||||
Ok(_) => println!("{} - VALID", instance_path_name),
|
||||
Err(errors) => {
|
||||
success = false;
|
||||
|
||||
println!("{} - INVALID. Errors:", instance_path_name);
|
||||
for (i, e) in errors.enumerate() {
|
||||
println!("{}. {}", i + 1, e);
|
||||
println!("{} - INVALID. Errors:", instance_path_name);
|
||||
for (i, e) in errors.enumerate() {
|
||||
println!("{}. {}", i + 1, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(error) => {
|
||||
println!("Schema is invalid. Error: {}", error);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(success)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//! Is able to load documents from remote locations via HTTP(S).
|
||||
use crate::{
|
||||
compilation::{DEFAULT_ROOT_URL, DEFAULT_SCOPE},
|
||||
error::{CompilationError, ValidationError},
|
||||
error::ValidationError,
|
||||
schemas::{id_of, Draft},
|
||||
};
|
||||
use ahash::AHashMap;
|
||||
|
@ -26,7 +26,7 @@ impl<'a> Resolver<'a> {
|
|||
scope: &Url,
|
||||
schema: &'a Value,
|
||||
store: AHashMap<String, Value>,
|
||||
) -> Result<Resolver<'a>, CompilationError> {
|
||||
) -> Result<Resolver<'a>, ValidationError<'a>> {
|
||||
let mut schemas = AHashMap::new();
|
||||
// traverse the schema and store all named ones under their canonical ids
|
||||
find_schemas(draft, schema, scope, &mut |id, schema| {
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{compilation::context::CompilationContext, keywords};
|
|||
use serde_json::{Map, Value};
|
||||
|
||||
/// JSON Schema Draft version
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq)]
|
||||
pub enum Draft {
|
||||
/// JSON Schema Draft 4
|
||||
Draft4,
|
||||
|
@ -18,8 +18,11 @@ impl Default for Draft {
|
|||
}
|
||||
}
|
||||
|
||||
type CompileFunc =
|
||||
fn(&Map<String, Value>, &Value, &CompilationContext) -> Option<keywords::CompilationResult>;
|
||||
type CompileFunc<'a> = fn(
|
||||
&'a Map<String, Value>,
|
||||
&'a Value,
|
||||
&CompilationContext,
|
||||
) -> Option<keywords::CompilationResult<'a>>;
|
||||
|
||||
impl Draft {
|
||||
pub(crate) fn get_validator(self, keyword: &str) -> Option<CompileFunc> {
|
||||
|
|
Loading…
Reference in New Issue