bringing back type constants for validation via new overrides vocabulary

This commit is contained in:
2025-10-08 12:38:26 -04:00
parent 44cde90c3d
commit f3d157ebcb
8 changed files with 202 additions and 228 deletions

View File

@ -370,7 +370,21 @@ impl ObjCompiler<'_, '_, '_, '_, '_, '_> {
}
}
s.properties = self.enqueue_map("properties");
if let Some(Value::Object(props_obj)) = self.value("properties") {
let mut properties = AHashMap::with_capacity(props_obj.len());
for (pname, pvalue) in props_obj {
let ptr = self.up.ptr.append2("properties", pname);
let sch_idx = self.enqueue_schema(ptr);
properties.insert(pname.clone(), sch_idx);
if let Some(prop_schema_obj) = pvalue.as_object() {
if let Some(Value::Bool(true)) = prop_schema_obj.get("override") {
s.override_properties.insert(pname.clone());
}
}
}
s.properties = properties;
}
s.pattern_properties = {
let mut v = vec![];
if let Some(Value::Object(obj)) = self.value("patternProperties") {

View File

@ -129,7 +129,7 @@ pub use {
use std::{borrow::Cow, collections::HashMap, error::Error, fmt::Display};
use ahash::AHashMap;
use ahash::{AHashMap, AHashSet};
use regex::Regex;
use serde_json::{Number, Value};
use util::*;
@ -238,6 +238,7 @@ struct Schema {
max_properties: Option<usize>,
required: Vec<String>,
properties: AHashMap<String, SchemaIndex>,
override_properties: AHashSet<String>,
pattern_properties: Vec<(Regex, SchemaIndex)>,
property_names: Option<SchemaIndex>,
additional_properties: Option<Additional>,

View File

@ -24,6 +24,9 @@
"type": ["object", "boolean"],
"$comment": "This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.",
"properties": {
"override": {
"type": "boolean"
},
"definitions": {
"$comment": "\"definitions\" has been replaced by \"$defs\".",
"type": "object",

View File

@ -1,9 +1,13 @@
use std::{borrow::Cow, cmp::min, collections::HashSet, fmt::Write};
use ahash::AHashSet;
use serde_json::{Map, Value};
use crate::{util::*, *};
#[derive(Default, Clone)]
struct Override<'s>(AHashSet<&'s str>);
macro_rules! prop {
($prop:expr) => {
InstanceToken::Prop(Cow::Borrowed($prop))
@ -37,6 +41,7 @@ pub(crate) fn validate<'s, 'v>(
schemas,
scope,
options,
overrides: Override::default(), // Start with an empty override context
uneval: Uneval::from(v, schema, options.be_strict),
errors: vec![],
bool_result: false,
@ -90,6 +95,7 @@ struct Validator<'v, 's, 'd, 'e> {
schemas: &'s Schemas,
scope: Scope<'d>,
options: ValidationOptions,
overrides: Override<'s>,
uneval: Uneval<'v>,
errors: Vec<ValidationError<'s, 'v>>,
bool_result: bool, // is interested to know valid or not (but not actuall error)
@ -190,7 +196,7 @@ impl<'v, 's> Validator<'v, 's, '_, '_> {
}
// type specific validations
impl<'v> Validator<'v, '_, '_, '_> {
impl<'v> Validator<'v, '_, '_,'_> {
fn obj_validate(&mut self, obj: &'v Map<String, Value>) {
let s = self.schema;
macro_rules! add_err {
@ -244,6 +250,11 @@ impl<'v> Validator<'v, '_, '_, '_> {
let mut additional_props = vec![];
for (pname, pvalue) in obj {
if self.overrides.0.contains(pname.as_str()) {
self.uneval.props.remove(pname);
continue;
}
if self.bool_result && !self.errors.is_empty() {
return;
}
@ -835,6 +846,11 @@ impl<'v, 's> Validator<'v, 's, '_, '_> {
new_options.be_strict = false;
}
let mut overrides = Override::default();
for pname in &schema.override_properties {
overrides.0.insert(pname.as_str());
}
let (result, _reply) = Validator {
v,
vloc: self.vloc,
@ -842,6 +858,7 @@ impl<'v, 's> Validator<'v, 's, '_, '_> {
schemas: self.schemas,
scope,
options: new_options,
overrides,
uneval: Uneval::from(v, schema, new_options.be_strict || !self.uneval.is_empty()),
errors: vec![],
bool_result: self.bool_result,
@ -872,6 +889,11 @@ impl<'v, 's> Validator<'v, 's, '_, '_> {
new_options.be_strict = false;
}
let mut overrides = self.overrides.clone();
for pname in &self.schema.override_properties {
overrides.0.insert(pname.as_str());
}
let (result, reply) = Validator {
v: self.v,
vloc: self.vloc,
@ -879,6 +901,7 @@ impl<'v, 's> Validator<'v, 's, '_, '_> {
schemas: self.schemas,
scope,
options: new_options,
overrides,
uneval: self.uneval.clone(),
errors: vec![],
bool_result: self.bool_result || bool_result,