Skip to content

Commit

Permalink
chore!: Remove deprecated ValidationErrorKind variants
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Dygalo <[email protected]>
  • Loading branch information
Stranger6667 committed Oct 26, 2024
1 parent b9d898b commit a989784
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 138 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Changed

- **BREAKING**: Remove unused `ValidationErrorKind::JSONParse`, `ValidationErrorKind::InvalidReference`, `ValidationErrorKind::Schema`, `ValidationErrorKind::FileNotFound` and `ValidationErrorKind::Utf8`.

### Performance

- Optimize error formatting in some cases.
Expand Down
70 changes: 0 additions & 70 deletions crates/jsonschema/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ use std::{
borrow::Cow,
error,
fmt::{self, Formatter, Write},
io,
iter::{empty, once},
str::Utf8Error,
string::FromUtf8Error,
};

Expand Down Expand Up @@ -87,18 +85,10 @@ pub enum ValidationErrorKind {
ExclusiveMinimum { limit: Value },
/// Everything is invalid for `false` schema.
FalseSchema,
/// If the referenced file is not found during ref resolution.
FileNotFound { error: io::Error },
/// When the input doesn't match to the specified format.
Format { format: String },
/// May happen in `contentEncoding` validation if `base64` encoded data is invalid.
FromUtf8 { error: FromUtf8Error },
/// Invalid UTF-8 string during percent encoding when resolving happens
Utf8 { error: Utf8Error },
/// May happen during ref resolution when remote document is not a valid JSON.
JSONParse { error: serde_json::Error },
/// `ref` value is not valid.
InvalidReference { reference: String },
/// Too many items in an array.
MaxItems { limit: u64 },
/// Value is too large.
Expand Down Expand Up @@ -131,8 +121,6 @@ pub enum ValidationErrorKind {
},
/// When a required property is missing.
Required { property: Value },
/// Resolved schema failed to compile.
Schema,
/// When the input value doesn't match one or multiple required types.
Type { kind: TypeKind },
/// Unexpected items.
Expand Down Expand Up @@ -398,14 +386,6 @@ impl<'a> ValidationError<'a> {
schema_path: location,
}
}
pub(crate) fn file_not_found(error: io::Error) -> ValidationError<'a> {
ValidationError {
instance_path: Location::new(),
instance: Cow::Owned(Value::Null),
kind: ValidationErrorKind::FileNotFound { error },
schema_path: Location::new(),
}
}
pub(crate) fn format(
location: Location,
instance_path: Location,
Expand All @@ -429,14 +409,6 @@ impl<'a> ValidationError<'a> {
schema_path: Location::new(),
}
}
pub(crate) fn json_parse(error: serde_json::Error) -> ValidationError<'a> {
ValidationError {
instance_path: Location::new(),
instance: Cow::Owned(Value::Null),
kind: ValidationErrorKind::JSONParse { error },
schema_path: Location::new(),
}
}
pub(crate) const fn max_items(
location: Location,
instance_path: Location,
Expand Down Expand Up @@ -633,15 +605,6 @@ impl<'a> ValidationError<'a> {
}
}

pub(crate) fn null_schema() -> ValidationError<'a> {
ValidationError {
instance_path: Location::new(),
instance: Cow::Owned(Value::Null),
kind: ValidationErrorKind::Schema,
schema_path: Location::new(),
}
}

pub(crate) const fn single_type_error(
location: Location,
instance_path: Location,
Expand Down Expand Up @@ -710,14 +673,6 @@ impl<'a> ValidationError<'a> {
schema_path: location,
}
}
pub(crate) fn utf8(error: Utf8Error) -> ValidationError<'a> {
ValidationError {
instance_path: Location::new(),
instance: Cow::Owned(Value::Null),
kind: ValidationErrorKind::Utf8 { error },
schema_path: Location::new(),
}
}
/// Create a new custom validation error.
pub fn custom(
location: Location,
Expand All @@ -737,12 +692,6 @@ impl<'a> ValidationError<'a> {
}

impl error::Error for ValidationError<'_> {}
impl From<serde_json::Error> for ValidationError<'_> {
#[inline]
fn from(err: serde_json::Error) -> Self {
ValidationError::json_parse(err)
}
}
impl From<referencing::Error> for ValidationError<'_> {
#[inline]
fn from(err: referencing::Error) -> Self {
Expand All @@ -754,34 +703,19 @@ impl From<referencing::Error> for ValidationError<'_> {
}
}
}
impl From<io::Error> for ValidationError<'_> {
#[inline]
fn from(err: io::Error) -> Self {
ValidationError::file_not_found(err)
}
}
impl From<FromUtf8Error> for ValidationError<'_> {
#[inline]
fn from(err: FromUtf8Error) -> Self {
ValidationError::from_utf8(err)
}
}
impl From<Utf8Error> for ValidationError<'_> {
#[inline]
fn from(err: Utf8Error) -> Self {
ValidationError::utf8(err)
}
}

/// Textual representation of various validation errors.
impl fmt::Display for ValidationError<'_> {
#[allow(clippy::too_many_lines)] // The function is long but it does formatting only
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match &self.kind {
ValidationErrorKind::Schema => f.write_str("Schema error"),
ValidationErrorKind::JSONParse { error } => error.fmt(f),
ValidationErrorKind::Referencing(error) => error.fmt(f),
ValidationErrorKind::FileNotFound { error } => error.fmt(f),
ValidationErrorKind::BacktrackLimitExceeded { error } => error.fmt(f),
ValidationErrorKind::Format { format } => {
write!(f, r#"{} is not a "{}""#, self.instance, format)
Expand Down Expand Up @@ -859,7 +793,6 @@ impl fmt::Display for ValidationError<'_> {
)
}
ValidationErrorKind::FromUtf8 { error } => error.fmt(f),
ValidationErrorKind::Utf8 { error } => error.fmt(f),
ValidationErrorKind::Enum { options } => {
write!(f, "{} is not one of {}", self.instance, options)
}
Expand All @@ -876,9 +809,6 @@ impl fmt::Display for ValidationError<'_> {
ValidationErrorKind::FalseSchema => {
write!(f, "False schema does not allow {}", self.instance)
}
ValidationErrorKind::InvalidReference { reference } => {
write!(f, "Invalid reference: {}", reference)
}
ValidationErrorKind::Maximum { limit } => write!(
f,
"{} is greater than the maximum of {}",
Expand Down
78 changes: 42 additions & 36 deletions crates/jsonschema/src/keywords/additional_properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::{
node::SchemaNode,
output::{Annotations, BasicOutput, OutputUnit},
paths::{LazyLocation, Location},
primitive_type::PrimitiveType,
properties::*,
validator::{PartialApplication, Validate},
};
Expand Down Expand Up @@ -1035,47 +1036,52 @@ pub(crate) fn compile<'a>(
if let Some(patterns) = parent.get("patternProperties") {
if let Value::Object(obj) = patterns {
// Compile all patterns & their validators to avoid doing work in the `patternProperties` validator
if let Ok(compiled_patterns) = compile_patterns(ctx, obj) {
match schema {
Value::Bool(true) => None, // "additionalProperties" are "true" by default
Value::Bool(false) => {
if let Some(properties) = properties {
compile_dynamic_prop_map_validator!(
AdditionalPropertiesWithPatternsNotEmptyFalseValidator,
properties,
ctx,
compiled_patterns,
)
} else {
Some(AdditionalPropertiesWithPatternsFalseValidator::compile(
ctx,
compiled_patterns,
))
}
let compiled_patterns = match compile_patterns(ctx, obj) {
Ok(patterns) => patterns,
Err(error) => return Some(Err(error)),
};
match schema {
Value::Bool(true) => None, // "additionalProperties" are "true" by default
Value::Bool(false) => {
if let Some(properties) = properties {
compile_dynamic_prop_map_validator!(
AdditionalPropertiesWithPatternsNotEmptyFalseValidator,
properties,
ctx,
compiled_patterns,
)
} else {
Some(AdditionalPropertiesWithPatternsFalseValidator::compile(
ctx,
compiled_patterns,
))
}
_ => {
if let Some(properties) = properties {
compile_dynamic_prop_map_validator!(
AdditionalPropertiesWithPatternsNotEmptyValidator,
properties,
ctx,
schema,
compiled_patterns,
)
} else {
Some(AdditionalPropertiesWithPatternsValidator::compile(
ctx,
schema,
compiled_patterns,
))
}
}
_ => {
if let Some(properties) = properties {
compile_dynamic_prop_map_validator!(
AdditionalPropertiesWithPatternsNotEmptyValidator,
properties,
ctx,
schema,
compiled_patterns,
)
} else {
Some(AdditionalPropertiesWithPatternsValidator::compile(
ctx,
schema,
compiled_patterns,
))
}
}
} else {
Some(Err(ValidationError::null_schema()))
}
} else {
Some(Err(ValidationError::null_schema()))
Some(Err(ValidationError::single_type_error(
Location::new(),
ctx.location().clone(),
schema,
PrimitiveType::Object,
)))
}
} else {
match schema {
Expand Down
7 changes: 0 additions & 7 deletions crates/jsonschema/src/keywords/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::{
ErrorIterator, ValidationError,
};
use serde_json::{Map, Value};
use std::fmt::{Display, Formatter};

pub(crate) struct CustomKeyword {
inner: Box<dyn Keyword>,
Expand All @@ -16,12 +15,6 @@ impl CustomKeyword {
}
}

impl Display for CustomKeyword {
fn fmt(&self, _: &mut Formatter<'_>) -> std::fmt::Result {
Ok(())
}
}

impl Validate for CustomKeyword {
fn validate<'i>(&self, instance: &'i Value, location: &LazyLocation) -> ErrorIterator<'i> {
self.inner.validate(instance, location)
Expand Down
33 changes: 21 additions & 12 deletions crates/jsonschema/src/keywords/legacy/type_draft_4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,12 @@ pub(crate) fn compile<'a>(
) -> Option<CompilationResult<'a>> {
let location = ctx.location().join("type");
match schema {
Value::String(item) => compile_single_type(item.as_str(), location),
Value::String(item) => Some(compile_single_type(item.as_str(), location, schema)),
Value::Array(items) => {
if items.len() == 1 {
let item = &items[0];
if let Value::String(item) = item {
compile_single_type(item.as_str(), location)
if let Value::String(ty) = item {
Some(compile_single_type(ty.as_str(), location, item))
} else {
Some(Err(ValidationError::single_type_error(
Location::new(),
Expand All @@ -151,15 +151,24 @@ pub(crate) fn compile<'a>(
}
}

fn compile_single_type<'a>(item: &str, location: Location) -> Option<CompilationResult<'a>> {
fn compile_single_type<'a>(
item: &str,
location: Location,
instance: &'a Value,
) -> CompilationResult<'a> {
match PrimitiveType::try_from(item) {
Ok(PrimitiveType::Array) => Some(type_::ArrayTypeValidator::compile(location)),
Ok(PrimitiveType::Boolean) => Some(type_::BooleanTypeValidator::compile(location)),
Ok(PrimitiveType::Integer) => Some(IntegerTypeValidator::compile(location)),
Ok(PrimitiveType::Null) => Some(type_::NullTypeValidator::compile(location)),
Ok(PrimitiveType::Number) => Some(type_::NumberTypeValidator::compile(location)),
Ok(PrimitiveType::Object) => Some(type_::ObjectTypeValidator::compile(location)),
Ok(PrimitiveType::String) => Some(type_::StringTypeValidator::compile(location)),
Err(()) => Some(Err(ValidationError::null_schema())),
Ok(PrimitiveType::Array) => type_::ArrayTypeValidator::compile(location),
Ok(PrimitiveType::Boolean) => type_::BooleanTypeValidator::compile(location),
Ok(PrimitiveType::Integer) => IntegerTypeValidator::compile(location),
Ok(PrimitiveType::Null) => type_::NullTypeValidator::compile(location),
Ok(PrimitiveType::Number) => type_::NumberTypeValidator::compile(location),
Ok(PrimitiveType::Object) => type_::ObjectTypeValidator::compile(location),
Ok(PrimitiveType::String) => type_::StringTypeValidator::compile(location),
Err(()) => Err(ValidationError::custom(
Location::new(),
location,
instance,
"Unexpected type",
)),
}
}
33 changes: 21 additions & 12 deletions crates/jsonschema/src/keywords/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,12 +299,12 @@ pub(crate) fn compile<'a>(
) -> Option<CompilationResult<'a>> {
let location = ctx.location().join("type");
match schema {
Value::String(item) => compile_single_type(item.as_str(), location),
Value::String(item) => Some(compile_single_type(item.as_str(), location, schema)),
Value::Array(items) => {
if items.len() == 1 {
let item = &items[0];
if let Value::String(item) = item {
compile_single_type(item.as_str(), location)
if let Value::String(ty) = item {
Some(compile_single_type(ty.as_str(), location, item))
} else {
Some(Err(ValidationError::single_type_error(
Location::new(),
Expand All @@ -328,16 +328,25 @@ pub(crate) fn compile<'a>(
}
}

fn compile_single_type(item: &str, location: Location) -> Option<CompilationResult> {
fn compile_single_type<'a>(
item: &str,
location: Location,
instance: &'a Value,
) -> CompilationResult<'a> {
match PrimitiveType::try_from(item) {
Ok(PrimitiveType::Array) => Some(ArrayTypeValidator::compile(location)),
Ok(PrimitiveType::Boolean) => Some(BooleanTypeValidator::compile(location)),
Ok(PrimitiveType::Integer) => Some(IntegerTypeValidator::compile(location)),
Ok(PrimitiveType::Null) => Some(NullTypeValidator::compile(location)),
Ok(PrimitiveType::Number) => Some(NumberTypeValidator::compile(location)),
Ok(PrimitiveType::Object) => Some(ObjectTypeValidator::compile(location)),
Ok(PrimitiveType::String) => Some(StringTypeValidator::compile(location)),
Err(()) => Some(Err(ValidationError::null_schema())),
Ok(PrimitiveType::Array) => ArrayTypeValidator::compile(location),
Ok(PrimitiveType::Boolean) => BooleanTypeValidator::compile(location),
Ok(PrimitiveType::Integer) => IntegerTypeValidator::compile(location),
Ok(PrimitiveType::Null) => NullTypeValidator::compile(location),
Ok(PrimitiveType::Number) => NumberTypeValidator::compile(location),
Ok(PrimitiveType::Object) => ObjectTypeValidator::compile(location),
Ok(PrimitiveType::String) => StringTypeValidator::compile(location),
Err(()) => Err(ValidationError::custom(
Location::new(),
location,
instance,
"Unexpected type",
)),
}
}

Expand Down
Loading

0 comments on commit a989784

Please sign in to comment.