use std::collections::HashMap;
use std::path::Path;
pub struct CommandValidator;
impl CommandValidator {
pub fn validate_command(
noun: &str,
verb: &str,
args: &[(&str, bool)], ) -> Result<(), ValidationError> {
if noun.is_empty() {
return Err(ValidationError::InvalidCommandName(
"Noun cannot be empty".to_string(),
));
}
if verb.is_empty() {
return Err(ValidationError::InvalidCommandName(
"Verb cannot be empty".to_string(),
));
}
for (arg_name, _required) in args {
if arg_name.is_empty() {
return Err(ValidationError::InvalidArgument(
"Argument name cannot be empty".to_string(),
));
}
}
Ok(())
}
pub fn get_registered_commands() -> HashMap<String, Vec<String>> {
let mut commands = HashMap::new();
commands.insert("ci".to_string(), vec!["workflow".to_string()]);
commands.insert("workflow".to_string(), vec!["init".to_string()]);
commands.insert(
"template".to_string(),
vec!["show".to_string(), "generate".to_string()],
);
commands.insert("graph".to_string(), vec!["query".to_string()]);
commands.insert("ontology".to_string(), vec!["extract".to_string()]);
commands.insert("project".to_string(), vec!["init".to_string()]);
commands
}
}
pub struct TestConfigValidator;
impl TestConfigValidator {
pub fn validate_clnrm_config(path: &Path) -> Result<(), ValidationError> {
if !path.exists() {
return Err(ValidationError::FileNotFound(
path.to_string_lossy().to_string(),
));
}
Ok(())
}
pub fn validate_all_clnrm_configs() -> Result<(), Vec<ValidationError>> {
let test_dir = Path::new("tests/clnrm");
let mut errors = Vec::new();
if test_dir.exists() {
let cli_commands = test_dir.join("cli_commands.clnrm.toml");
if let Err(e) = Self::validate_clnrm_config(&cli_commands) {
errors.push(e);
}
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
}
#[derive(Debug, Clone)]
pub enum ValidationError {
InvalidCommandName(String),
InvalidArgument(String),
FileNotFound(String),
InvalidConfig(String),
}
impl std::fmt::Display for ValidationError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ValidationError::InvalidCommandName(msg) => {
write!(f, "Invalid command name: {}", msg)
}
ValidationError::InvalidArgument(msg) => {
write!(f, "Invalid argument: {}", msg)
}
ValidationError::FileNotFound(path) => {
write!(f, "File not found: {}", path)
}
ValidationError::InvalidConfig(msg) => {
write!(f, "Invalid configuration: {}", msg)
}
}
}
}
impl std::error::Error for ValidationError {}
#[macro_export]
macro_rules! validate_command {
($noun:expr, $verb:expr, [$($arg:expr),*]) => {
const _: () = {
use $crate::validation::CommandValidator;
let args = [$($arg),*];
if let Err(e) = CommandValidator::validate_command($noun, $verb, &args) {
panic!("Command validation failed: {}", e);
}
};
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_command_validator() {
assert!(CommandValidator::validate_command("ci", "workflow", &[("name", false)]).is_ok());
}
#[test]
fn test_command_validator_empty_noun() {
assert!(CommandValidator::validate_command("", "workflow", &[]).is_err());
}
#[test]
fn test_test_config_validator() {
let path = Path::new("tests/clnrm/cli_commands.clnrm.toml");
let _ = TestConfigValidator::validate_clnrm_config(path);
}
}