feat: Add option to disable processing the `format` keyword
Prior to draft versions 2019-09, format validation is enabled by default (though should be able to be disabled), and vice versa afterword. This patch adds `should_validate_formats` to CompilationOptions to force the option one way or another. If not specified, it will fallback to a default based on the draft version (enabled by default before draft 2019-09). Closes #261
This commit is contained in:
parent
86bb87fa66
commit
aaadd99b2c
|
@ -7,6 +7,7 @@
|
|||
- `uuid` format validator. [#266](https://github.com/Stranger6667/jsonschema-rs/issues/266)
|
||||
- `duration` format validator. [#265](https://github.com/Stranger6667/jsonschema-rs/issues/265)
|
||||
- Collect annotations whilst evaulating schemas.[#262](https://github.com/Stranger6667/jsonschema-rs/issues/262)
|
||||
- Option to turn off processing of the `format` keyword. [#261](https://github.com/Stranger6667/jsonschema-rs/issues/261)
|
||||
- `basic` & `flag` output formatting styles. [#100](https://github.com/Stranger6667/jsonschema-rs/issues/100)
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -135,6 +135,7 @@ pub struct CompilationOptions {
|
|||
AHashMap<&'static str, Option<(ContentEncodingCheckType, ContentEncodingConverterType)>>,
|
||||
store: AHashMap<String, Arc<serde_json::Value>>,
|
||||
formats: AHashMap<&'static str, fn(&str) -> bool>,
|
||||
validate_formats: Option<bool>,
|
||||
validate_schema: bool,
|
||||
}
|
||||
|
||||
|
@ -147,6 +148,7 @@ impl Default for CompilationOptions {
|
|||
content_encoding_checks_and_converters: AHashMap::default(),
|
||||
store: AHashMap::default(),
|
||||
formats: AHashMap::default(),
|
||||
validate_formats: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -460,6 +462,18 @@ impl CompilationOptions {
|
|||
self.validate_schema = false;
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
/// Force enable or disable format validation.
|
||||
/// The default behavior is dependent on draft version, but the default behavior can be
|
||||
/// overridden to validate or not regardless of draft.
|
||||
pub fn should_validate_formats(&mut self, validate_formats: bool) -> &mut Self {
|
||||
self.validate_formats = Some(validate_formats);
|
||||
self
|
||||
}
|
||||
pub(crate) fn validate_formats(&self) -> bool {
|
||||
self.validate_formats
|
||||
.unwrap_or_else(|| self.draft().validate_formats_by_default())
|
||||
}
|
||||
}
|
||||
// format name & a pointer to a check function
|
||||
type FormatKV<'a> = Option<(&'a &'static str, &'a fn(&str) -> bool)>;
|
||||
|
|
|
@ -414,6 +414,10 @@ pub(crate) fn compile<'a>(
|
|||
schema: &'a Value,
|
||||
context: &CompilationContext,
|
||||
) -> Option<CompilationResult<'a>> {
|
||||
if !context.config.validate_formats() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Value::String(format) = schema {
|
||||
if let Some((format, func)) = context.config.format(format) {
|
||||
return Some(CustomFormatValidator::compile(context, format, *func));
|
||||
|
@ -503,6 +507,27 @@ mod tests {
|
|||
assert!(compiled.is_valid(&instance))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_validation() {
|
||||
let schema = json!({"format": "email", "type": "string"});
|
||||
let email_instance = json!("email@example.com");
|
||||
let not_email_instance = json!("foo");
|
||||
|
||||
let with_validation = JSONSchema::options()
|
||||
.should_validate_formats(true)
|
||||
.compile(&schema)
|
||||
.unwrap();
|
||||
let without_validation = JSONSchema::options()
|
||||
.should_validate_formats(false)
|
||||
.compile(&schema)
|
||||
.unwrap();
|
||||
|
||||
assert!(with_validation.is_valid(&email_instance));
|
||||
assert!(!with_validation.is_valid(¬_email_instance));
|
||||
assert!(without_validation.is_valid(&email_instance));
|
||||
assert!(without_validation.is_valid(¬_email_instance));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ecma_regex() {
|
||||
// See GH-230
|
||||
|
@ -526,6 +551,7 @@ mod tests {
|
|||
|
||||
let compiled = JSONSchema::options()
|
||||
.with_draft(Draft201909)
|
||||
.should_validate_formats(true)
|
||||
.compile(&schema)
|
||||
.unwrap();
|
||||
|
||||
|
@ -553,6 +579,7 @@ mod tests {
|
|||
|
||||
let compiled = JSONSchema::options()
|
||||
.with_draft(Draft201909)
|
||||
.should_validate_formats(true)
|
||||
.compile(&schema)
|
||||
.unwrap();
|
||||
|
||||
|
|
|
@ -22,6 +22,16 @@ impl Default for Draft {
|
|||
}
|
||||
}
|
||||
|
||||
impl Draft {
|
||||
pub(crate) const fn validate_formats_by_default(self) -> bool {
|
||||
match self {
|
||||
Draft::Draft4 | Draft::Draft6 | Draft::Draft7 => true,
|
||||
#[cfg(feature = "draft201909")]
|
||||
Draft::Draft201909 => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type CompileFunc<'a> = fn(
|
||||
&'a Map<String, Value>,
|
||||
&'a Value,
|
||||
|
|
|
@ -51,6 +51,7 @@ fn test_draft(_server_address: &str, test_case: TestCase) {
|
|||
let compiled = JSONSchema::options()
|
||||
.with_draft(draft_version)
|
||||
.with_meta_schemas()
|
||||
.should_validate_formats(true)
|
||||
.compile(&test_case.schema)
|
||||
.unwrap();
|
||||
|
||||
|
|
Loading…
Reference in New Issue