feat: support inline json schema validation dynamically

This commit is contained in:
2026-05-26 16:47:04 -04:00
parent 2c18163961
commit 0091e5c226

View File

@ -42,62 +42,83 @@ impl Validator {
} }
pub fn validate(&self, schema_id: &str, instance: &Value) -> crate::drop::Drop { pub fn validate(&self, schema_id: &str, instance: &Value) -> crate::drop::Drop {
let schema_opt = self.db.schemas.get(schema_id); let schema_arc = if schema_id.trim().starts_with('{') {
match serde_json::from_str::<crate::database::schema::Schema>(schema_id) {
if let Some(schema) = schema_opt { Ok(schema) => {
let ctx = ValidationContext::new( let mut errors = Vec::new();
&self.db, schema.compile(&self.db, "inline", "inline".to_string(), &mut errors);
&schema, if !errors.is_empty() {
&schema, return crate::drop::Drop::with_errors(errors);
instance,
HashSet::new(),
false,
false,
);
match ctx.validate_scoped() {
Ok(result) => {
if result.is_valid() {
crate::drop::Drop::success()
} else {
let errors: Vec<crate::drop::Error> = result
.errors
.into_iter()
.map(|e| crate::drop::Error {
code: e.code,
message: e.message,
details: crate::drop::ErrorDetails {
path: Some(e.path),
cause: None,
context: None,
schema: None,
},
})
.collect();
crate::drop::Drop::with_errors(errors)
} }
Arc::new(schema)
}
Err(e) => {
return crate::drop::Drop::with_errors(vec![crate::drop::Error {
code: "SCHEMA_PARSE_FAILED".to_string(),
message: format!("Failed to parse inline schema: {}", e),
details: crate::drop::ErrorDetails::default(),
}]);
} }
Err(e) => crate::drop::Drop::with_errors(vec![crate::drop::Error {
code: e.code,
message: e.message,
details: crate::drop::ErrorDetails {
path: Some(e.path),
cause: None,
context: None,
schema: None,
},
}]),
} }
} else { } else {
crate::drop::Drop::with_errors(vec![crate::drop::Error { match self.db.schemas.get(schema_id) {
code: "SCHEMA_NOT_FOUND".to_string(), Some(schema) => Arc::clone(schema),
message: format!("Schema {} not found", schema_id), None => {
return crate::drop::Drop::with_errors(vec![crate::drop::Error {
code: "SCHEMA_NOT_FOUND".to_string(),
message: format!("Schema {} not found", schema_id),
details: crate::drop::ErrorDetails {
path: Some("/".to_string()),
cause: None,
context: None,
schema: None,
},
}]);
}
}
};
let ctx = ValidationContext::new(
&self.db,
&schema_arc,
&schema_arc,
instance,
HashSet::new(),
false,
false,
);
match ctx.validate_scoped() {
Ok(result) => {
if result.is_valid() {
crate::drop::Drop::success()
} else {
let errors: Vec<crate::drop::Error> = result
.errors
.into_iter()
.map(|e| crate::drop::Error {
code: e.code,
message: e.message,
details: crate::drop::ErrorDetails {
path: Some(e.path),
cause: None,
context: None,
schema: None,
},
})
.collect();
crate::drop::Drop::with_errors(errors)
}
}
Err(e) => crate::drop::Drop::with_errors(vec![crate::drop::Error {
code: e.code,
message: e.message,
details: crate::drop::ErrorDetails { details: crate::drop::ErrorDetails {
path: Some("/".to_string()), path: Some(e.path),
cause: None, cause: None,
context: None, context: None,
schema: None, schema: None,
}, },
}]) }]),
} }
} }
} }