use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Command {
pub name: String,
pub description: String,
pub usage: String,
#[serde(default)]
pub aliases: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum CommandResult {
Success,
Failure(String),
NotHandled,
NeedsInput(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VanguardCommand {
pub name: String,
pub args: Vec<String>,
pub original: String,
}
#[derive(Debug, Clone)]
pub struct CommandContext {
pub cwd: std::path::PathBuf,
pub env: HashMap<String, String>,
pub interactive: bool,
pub data: HashMap<String, String>,
}
impl Default for CommandContext {
fn default() -> Self {
Self {
cwd: std::env::current_dir().unwrap_or_default(),
env: std::env::vars().collect(),
interactive: true,
data: HashMap::new(),
}
}
}
#[async_trait]
pub trait CommandHandler {
fn get_commands(&self) -> Vec<Command>;
async fn handle_command(
&self,
command: &VanguardCommand,
ctx: &CommandContext,
) -> CommandResult;
fn can_handle(&self, command_name: &str) -> bool {
self.get_commands()
.iter()
.any(|cmd| cmd.name == command_name || cmd.aliases.contains(&command_name.to_string()))
}
}