use std::collections::HashSet; use serde_json::Value; use crate::validator::context::ValidationContext; use crate::validator::error::ValidationError; use crate::validator::result::ValidationResult; impl<'a> ValidationContext<'a> { pub(crate) fn validate_dict( &self, result: &mut ValidationResult, ) -> Result { let current = self.instance; if let Some(obj) = current.as_object() { let is_dict = match &self.schema.type_ { Some(crate::database::object::SchemaTypeOrArray::Single(t)) => t == "dict", Some(crate::database::object::SchemaTypeOrArray::Multiple(types)) => types.contains(&"dict".to_string()), None => false, }; if is_dict { // Mark all keys as evaluated since a dictionary's keys are all dynamic parameters, not structured properties result.evaluated_keys.extend(obj.keys().cloned()); // Validate keys if let Some(ref keys_schema) = self.schema.keys { for key in obj.keys() { let _new_path = self.join_path(&format!("keys/{}", key)); let val_str = Value::String(key.to_string()); let ctx = self.derive( keys_schema, &val_str, &_new_path, HashSet::new(), self.extensible, self.reporter, None, ); result.merge(ctx.validate()?); } } // Validate items (values) if let Some(ref items_schema) = self.schema.items { for (key, child_instance) in obj { let new_path = self.join_path(key); let is_ref = match &items_schema.type_ { Some(crate::database::object::SchemaTypeOrArray::Single(ref_t)) => { !crate::database::object::is_primitive_type(ref_t) } _ => false, }; let next_extensible = if is_ref { false } else { self.extensible }; let derived = self.derive( items_schema, child_instance, &new_path, HashSet::new(), next_extensible, false, Some(self.instance), ); let item_res = derived.validate()?; result.merge(item_res); } } } } Ok(true) } }