Reputation: 1957
I'm trying to validate a JSON given a JSON file and a schema.
Schema:
{
"Address":{
"properties":{
"City":{
"type":"string"
},
"Country":{
"type":"string"
},
"Street":{
"type":"string"
}
},
"type":"object"
}
}
JSON:
{
"Address":{
"Street":"Downing Street 10",
"City":"London",
"Country":"Great Britain"
}
}
My Rust file:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate valico;
use std::fs::File;
use std::io::Read;
use serde_json::Value;
use valico::json_dsl;
use valico::json_schema;
fn main() {
let mut schemaFile = File::open("src/schema.json").unwrap();
let mut jsonSchemaString = String::new();
schemaFile.read_to_string(&mut jsonSchemaString).unwrap();
let json_v4_schema: Value = serde_json::from_str(&jsonSchemaString).unwrap();
let state = jsonSchemaString.process(&mut json_v4_schema, &None); //this is wrong as jsonSchemaString is not a jsonDsl.
println!("Is valid: {}", state.is_valid())
}
I'm trying to use valico for the JSON validation, but I cant figure out how to pass the schema against which the JSON has to be validated. I have seen examples where a JsonDsl
is built using the valico builder, but how do I do it if I already have a JSON schema and I want to validate against that? Is there any other way that I can achieve this?
Upvotes: 7
Views: 4851
Reputation: 1416
Late to the party here, but in case anyone else is having trouble with this, below is a MVCE I've adjusted to using the schema and data you used as an example. I included the strings directly in the code for "simplicity", but you can just replace that with fs::File
/io::Read
operations you already had.
extern crate serde_json;
extern crate valico;
use serde_json::from_str;
use valico::json_schema;
fn main() {
let s = from_str(r#"
{
"Address": {
"Street":"Downing Street 10",
"City":"London",
"Country":"Great Britain"
}
}
"#).unwrap();
let j_schema = from_str(r#"
{
"type": "object",
"properties": {
"Address": {
"type": "object",
"properties": {
"Country": {
"type": "string"
},
"Street": {
"type": "string"
}
},
"required": ["Country", "Street"]
}
},
"required": ["Address"]
}
"#).unwrap();
let mut scope = json_schema::Scope::new();
let r_schema = scope.compile_and_return(j_schema, true).ok().unwrap();
println!("Is valid: {}", r_schema.validate(&s).is_valid())
}
Running this prints Is valid: true
. Changing the "Address" to "Addresses" and running it again prints Is valid: false
Please note that I had to make some small adjustments to your schema. First, to verify that valico is validating it correctly I set required fields. Secondly, since the root object doesn't have a name (it's only {}
) the "Address" would be a property of that root object.
So instead of
{
"Address": {
"properties": {
...
it is instead
{
"type": "object",
"properties": {
"Address": {
"type": "object",
....
Also, it seems like valico requires an older version of serde_json, so I added this as dependency in my Cargo.toml
serde_json = "0.8"
Upvotes: 7
Reputation: 1
I guess you can try this:
use valico::json_dsl;
use serde_json::{from_str, to_string_pretty}
...
let params = json_dsl::Builder::build(|params| {
// code here
});
let mut obj = from_str(&jsonSchemaString).unwrap();
let state = params.process(&mut obj, &None);
Instead of using a type Value. This should work.
Upvotes: 0