jsonschema-rs
jsonschema-rs copied to clipboard
Refactor keywords into "basic" keywords and "composite" keywords
The goal of this issue is to track the effort needed to create a well defined structure for:
- "basic" keywords: keywords that should be validated in isolation
- "composite" keywords": multiple keywords that can be validated together
At the current stage (9767a9f921a85bc8295b0405f19ee64f48953b4c) we already a single case of composite keywords:
-
contentEncoding
andcontentMediaType
The idea of creating such structure would allow us to:
- extend the set of composite keywords as needed (#79)
- keep better code separation between the keyword implementation and a "macro-keyword" one
Ideally the compile_validators
should be looking like
let mut validators = Vec::with_capacity(object.len());
/* START NEW */
let mut object_keywords = object.keys().collect::<HashSet<_>>();
for (keywords, compilation_func) in get_all_composite_validators_for_draft(context.draft) {
if ! object_keywords contains all keywords ! {
if let Some(validator) = compilation_func(object, subschema, &context) {
validators.push(validator?);
! Discard used keywords !
}
}
}
}
/* END NEW */
for keyword in object_keywords { // object_keywords will contain the not used keywords
if let Some(compilation_func) = context.draft.get_validator(keyword) {
if let Some(validator) = compilation_func(object, object.get(keyword).unwrap(), &context) {
validators.push(validator?)
}
}
}
Ok(validators)
This is just a rough idea, and I'm looking for feedbacks before trying something in this regard. I think that having a better structure would allow us
- to easily tackle #79 as hooking the logic into the code would be simpler
- eventually allow us to enable/disable the composite keywords concept via cargo features or
JSONSchema::compile
flags
I'll try to provide some feedback tomorrow
Yep, it does sound right to me! :) However, I think that in the end there will be no "basic" keywords - probably all keywords can be combined and at maximum, there will be 2 validators - 1 for all types (e.g. type
+ allOf
) and 1 type-specific, so 1-keyword validators will be the same as composite ones, i.e. they are special cases. At least it feels this way at the moment, but I think we should move in this direction. I can imagine that the perfect case for dynamic validator creation might look like this - the minimum dispatching case I see is possible is to have 2 validators, one is applied unconditionally since it is for any type and one is applied conditionally, depends on the input type.
Let me know what do you think
I see your point on "there will be no basic keywords", the aspect that I would highlight in here is that using composite keywords is a way of improving performances but at the same time increase complexity and so it might expose us to potential bugs.
By still implementing the handling of 1-keyword validators we could allow to enable-disable the composite keywords concept at library compile time (via Cargo-feature) or at JSONSchema compile time (via a flag on the compile_validators
method). Doing this would allow us to buy some time in case of a new bug is discovered (NOTE: This assumes that we're fairly confident with the 1-keywords implementations 😎 )
I'll try to make some progress on this, I'm aware that this is not top-priority but it would enable us to start creating n-keywords validators that would allow to enhance performances