feat: optional unknown formats as compilation error

This commit is contained in:
Pawel Iwan 2022-06-23 08:59:25 +02:00 committed by Dmitry Dygalo
parent 5da86850ab
commit 71a511d634
2 changed files with 43 additions and 2 deletions

View File

@ -221,6 +221,7 @@ pub struct CompilationOptions {
formats: AHashMap<&'static str, fn(&str) -> bool>,
validate_formats: Option<bool>,
validate_schema: bool,
ignore_unknown_formats: bool,
}
impl Default for CompilationOptions {
@ -234,6 +235,7 @@ impl Default for CompilationOptions {
store: AHashMap::default(),
formats: AHashMap::default(),
validate_formats: None,
ignore_unknown_formats: true,
}
}
}
@ -568,6 +570,20 @@ impl CompilationOptions {
self.validate_formats
.unwrap_or_else(|| self.draft().validate_formats_by_default())
}
/// Set the `false` if unrecognized formats should be reported as a validation error.
/// By default unknown formats are silently ignored.
pub fn should_ignore_unknown_formats(
&mut self,
should_ignore_unknown_formats: bool,
) -> &mut Self {
self.ignore_unknown_formats = should_ignore_unknown_formats;
self
}
pub(crate) const fn are_unknown_formats_ignored(&self) -> bool {
self.ignore_unknown_formats
}
}
// format name & a pointer to a check function
type FormatKV<'a> = Option<(&'a &'static str, &'a fn(&str) -> bool)>;

View File

@ -493,7 +493,18 @@ pub(crate) fn compile<'a>(
"duration" if draft_version == Draft::Draft201909 => {
Some(DurationValidator::compile(context))
}
_ => None,
_ => {
if context.config.are_unknown_formats_ignored() {
None
} else {
return Some(Err(ValidationError::format(
JSONPointer::default(),
context.clone().schema_path.into(),
schema,
"unknown format",
)));
}
}
}
} else {
Some(Err(ValidationError::single_type_error(
@ -511,7 +522,7 @@ mod tests {
#[cfg(feature = "draft201909")]
use crate::schemas::Draft::Draft201909;
use crate::{compilation::JSONSchema, tests_util};
use crate::{compilation::JSONSchema, error::ValidationErrorKind, tests_util};
#[test]
fn ignored_format() {
@ -606,4 +617,18 @@ mod tests {
assert!(!compiled.is_valid(&failing_instance));
}
}
#[test]
fn unknown_formats_should_not_be_ignored() {
let schema = json!({ "format": "custom", "type": "string"});
let validation_error = JSONSchema::options()
.should_ignore_unknown_formats(false)
.compile(&schema)
.expect_err("the validation error should be returned");
assert!(
matches!(validation_error.kind, ValidationErrorKind::Format { format } if format == "unknown format")
);
assert_eq!("\"custom\"", validation_error.instance.to_string())
}
}