validator refactor progress

This commit is contained in:
2026-03-03 00:13:37 -05:00
parent e14f53e7d9
commit 3898c43742
81 changed files with 6331 additions and 7934 deletions

View File

@ -0,0 +1,119 @@
use serde_json::Value;
use std::collections::HashSet;
use crate::validator::context::ValidationContext;
use crate::validator::error::ValidationError;
use crate::validator::result::ValidationResult;
impl<'a> ValidationContext<'a> {
pub(crate) fn validate_array(
&self,
result: &mut ValidationResult,
) -> Result<bool, ValidationError> {
let current = self.instance;
if let Some(arr) = current.as_array() {
if let Some(min) = self.schema.min_items {
if (arr.len() as f64) < min {
result.errors.push(ValidationError {
code: "MIN_ITEMS".to_string(),
message: "Too few items".to_string(),
path: self.path.to_string(),
});
}
}
if let Some(max) = self.schema.max_items {
if (arr.len() as f64) > max {
result.errors.push(ValidationError {
code: "MAX_ITEMS".to_string(),
message: "Too many items".to_string(),
path: self.path.to_string(),
});
}
}
if self.schema.unique_items.unwrap_or(false) {
let mut seen: Vec<&Value> = Vec::new();
for item in arr {
if seen.contains(&item) {
result.errors.push(ValidationError {
code: "UNIQUE_ITEMS_VIOLATED".to_string(),
message: "Array has duplicate items".to_string(),
path: self.path.to_string(),
});
break;
}
seen.push(item);
}
}
if let Some(ref contains_schema) = self.schema.contains {
let mut _match_count = 0;
for (i, child_instance) in arr.iter().enumerate() {
let derived = self.derive(
contains_schema,
child_instance,
&self.path,
self.extensible,
false,
);
let check = derived.validate()?;
if check.is_valid() {
_match_count += 1;
result.evaluated_indices.insert(i);
}
}
let min = self.schema.min_contains.unwrap_or(1.0) as usize;
if _match_count < min {
result.errors.push(ValidationError {
code: "CONTAINS_VIOLATED".to_string(),
message: format!("Contains matches {} < min {}", _match_count, min),
path: self.path.to_string(),
});
}
if let Some(max) = self.schema.max_contains {
if _match_count > max as usize {
result.errors.push(ValidationError {
code: "CONTAINS_VIOLATED".to_string(),
message: format!("Contains matches {} > max {}", _match_count, max),
path: self.path.to_string(),
});
}
}
}
let len = arr.len();
let mut validation_index = 0;
if let Some(ref prefix) = self.schema.prefix_items {
for (i, sub_schema) in prefix.iter().enumerate() {
if i < len {
let path = format!("{}/{}", self.path, i);
if let Some(child_instance) = arr.get(i) {
let derived = self.derive(sub_schema, child_instance, &path, self.extensible, false);
let item_res = derived.validate()?;
result.merge(item_res);
result.evaluated_indices.insert(i);
validation_index += 1;
}
}
}
}
if let Some(ref items_schema) = self.schema.items {
for i in validation_index..len {
let path = format!("{}/{}", self.path, i);
if let Some(child_instance) = arr.get(i) {
let derived = self.derive(items_schema, child_instance, &path, self.extensible, false);
let item_res = derived.validate()?;
result.merge(item_res);
result.evaluated_indices.insert(i);
}
}
}
}
Ok(true)
}
}