(
&self,
data: &serde_json::Value,
schema: &serde_json::Value,
path: &str,
)
| 198 | /// Validate JSON value against schema |
| 199 | #[allow(clippy::only_used_in_recursion)] |
| 200 | fn validate_json_against_schema( |
| 201 | &self, |
| 202 | data: &serde_json::Value, |
| 203 | schema: &serde_json::Value, |
| 204 | path: &str, |
| 205 | ) -> ValidationResult { |
| 206 | let mut result = ValidationResult::success(); |
| 207 | |
| 208 | // Extract schema properties |
| 209 | let schema_obj = match schema.as_object() { |
| 210 | Some(obj) => obj, |
| 211 | None => { |
| 212 | result.add_error(ValidationError::new( |
| 213 | path, |
| 214 | "Schema must be an object", |
| 215 | "INVALID_SCHEMA", |
| 216 | )); |
| 217 | return result; |
| 218 | } |
| 219 | }; |
| 220 | |
| 221 | // Check type |
| 222 | if let Some(expected_type) = schema_obj.get("type").and_then(|t| t.as_str()) { |
| 223 | let actual_type = match data { |
| 224 | serde_json::Value::Null => "null", |
| 225 | serde_json::Value::Bool(_) => "boolean", |
| 226 | serde_json::Value::Number(_) => "number", |
| 227 | serde_json::Value::String(_) => "string", |
| 228 | serde_json::Value::Array(_) => "array", |
| 229 | serde_json::Value::Object(_) => "object", |
| 230 | }; |
| 231 | |
| 232 | if expected_type != actual_type { |
| 233 | result.add_error( |
| 234 | ValidationError::new(path, "Type mismatch".to_string(), "TYPE_MISMATCH") |
| 235 | .with_expected(expected_type) |
| 236 | .with_actual(actual_type), |
| 237 | ); |
| 238 | return result; |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | // Validate object properties |
| 243 | if let (Some(data_obj), Some(properties)) = ( |
| 244 | data.as_object(), |
| 245 | schema_obj.get("properties").and_then(|p| p.as_object()), |
| 246 | ) { |
| 247 | // Check required properties |
| 248 | if let Some(required) = schema_obj.get("required").and_then(|r| r.as_array()) { |
| 249 | for req_prop in required { |
| 250 | if let Some(prop_name) = req_prop.as_str() { |
| 251 | if !data_obj.contains_key(prop_name) { |
| 252 | result.add_error(ValidationError::new( |
| 253 | format!("{path}.{prop_name}"), |
| 254 | format!("Required property '{prop_name}' is missing"), |
| 255 | "MISSING_REQUIRED_PROPERTY", |
| 256 | )); |
| 257 | } |
no test coverage detected