Files
jspg/src/validator/mod.rs

107 lines
2.6 KiB
Rust

use std::collections::{HashMap, HashSet};
pub mod context;
pub mod error;
pub mod result;
pub mod rules;
pub use context::ValidationContext;
pub use error::ValidationError;
pub use result::ValidationResult;
use crate::database::Database;
use crate::validator::rules::util::is_integer;
use serde_json::Value;
use std::sync::Arc;
use crate::drop::{Drop, Error, ErrorDetails};
pub struct Validator {
pub db: Arc<Database>,
}
impl Validator {
pub fn new(db: Arc<Database>) -> Self {
Self { db }
}
pub fn check_type(t: &str, val: &Value) -> bool {
if let Value::String(s) = val
&& s.is_empty()
{
return true;
}
match t {
"null" => val.is_null(),
"boolean" => val.is_boolean(),
"string" => val.is_string(),
"number" => val.is_number(),
"integer" => is_integer(val),
"object" => val.is_object(),
"array" => val.is_array(),
_ => true,
}
}
pub fn validate(&self, schema_id: &str, instance: &Value) -> crate::drop::Drop {
let schema_opt = self.db.schemas.get(schema_id);
if let Some(schema) = schema_opt {
let ctx = ValidationContext::new(
&self.db,
&schema,
&schema,
instance,
HashSet::new(),
false,
false,
);
match ctx.validate_scoped() {
Ok(result) => {
if result.is_valid() {
Drop::success()
} else {
let errors: Vec<Error> = result
.errors
.into_iter()
.map(|e| Error {
code: e.code,
values: e.values,
details: ErrorDetails {
path: Some(e.path),
cause: None,
context: None,
schema: Some(schema_id.to_string()),
},
})
.collect();
Drop::with_errors(errors)
}
}
Err(e) => Drop::with_errors(vec![Error {
code: e.code,
values: e.values,
details: ErrorDetails {
path: Some(e.path),
cause: None,
context: None,
schema: Some(schema_id.to_string()),
},
}]),
}
} else {
Drop::with_errors(vec![Error {
code: "SCHEMA_NOT_FOUND".to_string(),
values: Some(HashMap::from([
("schema".to_string(), schema_id.to_string()),
])),
details: ErrorDetails {
path: Some("/".to_string()),
cause: None,
context: None,
schema: Some(schema_id.to_string()),
},
}])
}
}
}