use ggen_utils::error::Result;
use std::path::PathBuf;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ValidateInput {
pub pack_path: PathBuf,
pub strict: bool,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct ValidateOutput {
pub valid: bool,
pub score: u8,
#[serde(default)]
pub errors: Vec<String>,
#[serde(default)]
pub warnings: Vec<String>,
pub stats: ValidationStats,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct ValidationStats {
pub ontologies_checked: usize,
pub templates_checked: usize,
pub issues_found: usize,
pub validation_time_ms: u64,
}
pub async fn execute_validate(input: &ValidateInput) -> Result<ValidateOutput> {
let start_time = std::time::Instant::now();
if !input.pack_path.exists() {
return Err(ggen_utils::error::Error::new(&format!(
"Pack directory not found: {}",
input.pack_path.display()
)));
}
let gpack_path = input.pack_path.join("gpack.toml");
if !gpack_path.exists() {
return Err(ggen_utils::error::Error::new(
"gpack.toml not found in pack",
));
}
let errors = Vec::new();
let warnings = Vec::new();
let elapsed = start_time.elapsed();
let stats = ValidationStats {
ontologies_checked: 0,
templates_checked: 0,
issues_found: errors.len() + warnings.len(),
validation_time_ms: elapsed.as_millis() as u64,
};
let valid = (!input.strict || warnings.is_empty()) && errors.is_empty();
let score = if valid { 100 } else { 50 };
Ok(ValidateOutput {
valid,
score,
errors,
warnings,
stats,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_validate_missing_pack() {
let input = ValidateInput {
pack_path: PathBuf::from("/nonexistent/pack"),
strict: false,
};
let result = execute_validate(&input).await;
assert!(result.is_err());
}
}