use std::collections::HashMap;
use std::sync::Arc;
use jsonschema::{Draft, JSONSchema};
use serde_json::Value;
use crate::error::{Error, Result};
#[derive(Debug, Clone)]
pub struct ParameterValidator {
schema: Arc<JSONSchema>,
static_validators: HashMap<String, Arc<JSONSchema>>,
}
impl ParameterValidator {
pub fn new(schema: Value) -> Result<Self> {
let compiled = JSONSchema::options()
.with_draft(Draft::Draft7)
.compile(&schema)
.map_err(|e| Error::InvalidInput(format!("无效的JSON Schema: {e}")))?;
Ok(Self {
schema: Arc::new(compiled),
static_validators: HashMap::new(),
})
}
pub fn with_validator(mut self, name: &str, schema: Value) -> Result<Self> {
let compiled = JSONSchema::options()
.with_draft(Draft::Draft7)
.compile(&schema)
.map_err(|e| Error::InvalidInput(format!("无效的字段验证器: {e}")))?;
self.static_validators
.insert(name.to_string(), Arc::new(compiled));
Ok(self)
}
pub fn validate(&self, params: &Value) -> Result<()> {
let result = self.schema.validate(params);
if let Err(errors) = result {
let error_messages: Vec<String> = errors
.map(|e| format!("Path '{}': {}", e.instance_path, e))
.collect();
return Err(Error::InvalidInput(format!(
"参数验证失败: {}",
error_messages.join("; ")
)));
}
for (field, validator) in &self.static_validators {
if let Some(value) = params.get(field) {
let result = validator.validate(value);
if let Err(errors) = result {
let error_messages: Vec<String> = errors.map(|e| format!("{e}")).collect();
return Err(Error::InvalidInput(format!(
"字段 '{}' 验证失败: {}",
field,
error_messages.join("; ")
)));
}
}
}
Ok(())
}
}