-
-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEATURE] User-defined validation for the format
keyword
#158
Comments
format
keyword
I will attempt to work on this on my own fork. Any comments on how you want the api to look? or is the proposed api acceptable? |
Hi @JCBurnside ! Thank you for taking a step! :) I think that the most important measure is ergonomics and I'll be happy to discuss any other API design options :) Probably the draft above could be a good start for experimenting with the API design. The end goal is probably to let the user specify only the validation function (maybe wrapped in some proc macro) and put it somehow to the compiled schema. So the user won't need to create a struct, implement trait, etc. Something like this maybe? #[jsonschema::format]
fn custom(value: &str) -> bool {
value == "bar"
}
fn main() {
...
let compiled = jsonschema::JSONSchema::options()
.format("custom", custom)
.compile(&schema)
.expect("Invalid schema");
} |
Hi, Thanks for the quick response. That does seem like an elegant solution but shouldn't it take a |
The thing is that the format_validator!(DateTimeValidator, "date-time");
impl Validate for DateTimeValidator {
validate!("date-time");
fn is_valid(&self, _: &JSONSchema, instance: &Value) -> bool {
if let Value::String(item) = instance {
DateTime::parse_from_rfc3339(item).is_ok()
} else {
true
}
}
} All format validators return So, as the type checking is generally redundant for this case, I think it should not be exposed to the end-user. |
I see. I will consider it. |
Problem with proc macros is to export them it must be the only type of thing you export at the moment. I could create a secondary crate that adds the feature? |
Yep, I think it could be |
Though do we even need the attribute? |
The main reason to have it is to avoid overhead (minor, though) at runtime. The underlying compilation process relies on structs that implement the Btw, with such an attribute, it will be possible to avoid tons of boilerplate in |
Problem i see with using the proc macro is instead of passing |
Yep, it sounds like it could be solved this way, indeed. |
For people who are coming here from "This Week In Rust 388" (as I submitted only this exact issue): If you feel like you'd like to work on some issue - feel free to take a look at:
Or any other in the issue tracker, I'd be happy to provide support :) |
An extra thought about storing things in this snippet. I think that the macro can additionally generate a compilation function (similar to this one, but maybe simpler). Then it should be alright to store some format name -> compile function mapping |
Hi @JCBurnside ! Let me know if I can help here :) I saw your fork, it looks good to me :) |
I am not quite sure how to get what you suggested to work. I am struggling to understand how the system works as it is. |
@JCBurnside I want to thank you for your efforts and sorry again for giving misleading advice. |
At the moment,
jsonschema
supports theformat
keyword for formats defined in Drafts 4, 6, 7. However, JSON Schema allows custom values for theformat
keyword.It will be awesome to provide a way for the end-user to validate their own formats.
As all validators are "compiled" to some structs (to avoid some run-time overhead e.g., map lookup, etc.), I think that the public API might look like this:
It will be nice to avoid the boilerplate that extracts the actual string from
Value::String
, so the user won't write this code for each format.Anticipated changes to implement this:
CompilationOptions
builder to handle formats;format.rs
take a look at this mapping before going to take a look at the built-in validators;Validate
trait public and implement some trait on top of it to avoid boilerplate?For now, I think it is OK to keep the scope on the Rust code only. A similar feature for bindings could be implemented later.
The text was updated successfully, but these errors were encountered: