use crate::validator::context::ValidationContext; use crate::validator::error::ValidationError; use crate::validator::result::ValidationResult; use crate::database::realm::SchemaRealm; impl<'a> ValidationContext<'a> { pub(crate) fn validate_family( &self, result: &mut ValidationResult, ) -> Result { if self.schema.family.is_some() { let conflicts = self.schema.type_.is_some() || self.schema.properties.is_some() || self.schema.required.is_some() || self.schema.additional_properties.is_some() || self.schema.items.is_some() || self.schema.cases.is_some() || self.schema.one_of.is_some() || self.schema.enum_.is_some() || self.schema.const_.is_some(); if conflicts { result.errors.push(ValidationError { code: "INVALID_SCHEMA".to_string(), message: "family must be used exclusively without other constraints".to_string(), path: self.path.to_string(), }); return Ok(false); } } if self.schema.family.is_some() { if let Some(options) = self.schema.compiled_options.get() { return self.execute_polymorph(options, result); } else { result.errors.push(ValidationError { code: "UNCOMPILED_FAMILY".to_string(), message: "Encountered family block that could not be mapped to deterministic options during db schema compilation.".to_string(), path: self.path.to_string(), }); return Ok(false); } } Ok(true) } pub(crate) fn validate_one_of( &self, result: &mut ValidationResult, ) -> Result { if self.schema.one_of.is_some() { if let Some(options) = self.schema.compiled_options.get() { return self.execute_polymorph(options, result); } else { result.errors.push(ValidationError { code: "UNCOMPILED_ONEOF".to_string(), message: "Encountered oneOf block that could not be mapped to deterministic compiled options natively.".to_string(), path: self.path.to_string(), }); return Ok(false); } } Ok(true) } pub(crate) fn execute_polymorph( &self, options: &std::collections::BTreeMap, Option)>, result: &mut ValidationResult, ) -> Result { // 1. O(1) Fast-Path Router & Extractor let instance_val = if let Some(disc) = self.schema.compiled_discriminator.get() { let val = self .instance .as_object() .and_then(|o| o.get(disc)) .and_then(|t| t.as_str()); if val.is_some() { result.evaluated_keys.insert(disc.to_string()); } val.map(|s| s.to_string()) } else { match self.instance { serde_json::Value::Null => Some("null".to_string()), serde_json::Value::Bool(_) => Some("boolean".to_string()), serde_json::Value::Number(n) => { if n.is_i64() || n.is_u64() { Some("integer".to_string()) } else { Some("number".to_string()) } } serde_json::Value::String(_) => Some("string".to_string()), serde_json::Value::Array(_) => Some("array".to_string()), serde_json::Value::Object(_) => Some("object".to_string()), } }; if let Some(val) = instance_val { if let Some((idx_opt, target_id_opt)) = options.get(&val) { if let Some(target_id) = target_id_opt { if let Some(target_schema) = self.db.get_scoped_schema(SchemaRealm::Type, target_id) { let derived = self.derive_for_schema(&target_schema, false); let sub_res = derived.validate()?; let is_valid = sub_res.is_valid(); result.merge(sub_res); return Ok(is_valid); } else { result.errors.push(ValidationError { code: "MISSING_COMPILED_SCHEMA".to_string(), message: format!( "Polymorphic router target '{}' does not exist in the database schemas map", target_id ), path: self.path.to_string(), }); return Ok(false); } } else if let Some(idx) = idx_opt { if let Some(target_schema) = self .schema .one_of .as_ref() .and_then(|options| options.get(*idx)) { let derived = self.derive_for_schema(target_schema.as_ref(), false); let sub_res = derived.validate()?; let is_valid = sub_res.is_valid(); result.merge(sub_res); return Ok(is_valid); } else { result.errors.push(ValidationError { code: "MISSING_COMPILED_SCHEMA".to_string(), message: format!( "Polymorphic index target '{}' does not exist in the local oneOf array", idx ), path: self.path.to_string(), }); return Ok(false); } } else { return Ok(false); } } else { let disc_msg = if let Some(d) = self.schema.compiled_discriminator.get() { format!("discriminator {}='{}'", d, val) } else { format!("structural JSON base primitive '{}'", val) }; result.errors.push(ValidationError { code: if self.schema.family.is_some() { "NO_FAMILY_MATCH".to_string() } else { "NO_ONEOF_MATCH".to_string() }, message: format!( "Payload matched no candidate boundaries based on its {}", disc_msg ), path: self.path.to_string(), }); return Ok(false); } } else { if let Some(d) = self.schema.compiled_discriminator.get() { result.errors.push(ValidationError { code: "MISSING_TYPE".to_string(), message: format!( "Missing explicit '{}' discriminator. Unable to resolve polymorphic boundaries", d ), path: self.path.to_string(), }); } return Ok(false); } } pub(crate) fn validate_type_inheritance( &self, result: &mut ValidationResult, ) -> Result { // Core inheritance logic replaces legacy routing let payload_primitive = match self.instance { serde_json::Value::Null => "null", serde_json::Value::Bool(_) => "boolean", serde_json::Value::Number(n) => { if n.is_i64() || n.is_u64() { "integer" } else { "number" } } serde_json::Value::String(_) => "string", serde_json::Value::Array(_) => "array", serde_json::Value::Object(_) => "object", }; let mut custom_types = Vec::new(); match &self.schema.type_ { Some(crate::database::object::SchemaTypeOrArray::Single(t)) => { if !crate::database::object::is_primitive_type(t) { custom_types.push(t.clone()); } } Some(crate::database::object::SchemaTypeOrArray::Multiple(arr)) => { if arr.contains(&payload_primitive.to_string()) || (payload_primitive == "integer" && arr.contains(&"number".to_string())) { // It natively matched a primitive in the array options, skip forcing custom proxy fallback } else { for t in arr { if !crate::database::object::is_primitive_type(t) { custom_types.push(t.clone()); } } } } None => {} } for t in custom_types { if let Some(global_schema) = self.db.get_scoped_schema(SchemaRealm::Type, &t) { let mut new_overrides = self.overrides.clone(); if let Some(props) = &self.schema.properties { new_overrides.extend(props.keys().map(|k| k.to_string())); } let mut shadow = self.derive( &global_schema, self.instance, &self.path, new_overrides, self.extensible, true, // Reporter mode ); shadow.root = &global_schema; result.merge(shadow.validate()?); } else { result.errors.push(ValidationError { code: "INHERITANCE_RESOLUTION_FAILED".to_string(), message: format!( "Inherited entity pointer '{}' was not found in schema registry", t ), path: self.path.to_string(), }); } } Ok(true) } }