vanguard-plugin-sdk 0.1.4

SDK for developing Vanguard plugins
Documentation
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// Represents a plugin command
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Command {
    /// The name of the command (e.g., "hello")
    pub name: String,
    /// Brief description of what the command does
    pub description: String,
    /// Usage example (e.g., "plugin-name hello [name]")
    pub usage: String,
    /// Optional aliases for the command
    #[serde(default)]
    pub aliases: Vec<String>,
}

/// Result of a command execution
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum CommandResult {
    /// Command executed successfully
    Success,
    /// Command failed with an error message
    Failure(String),
    /// Command was not handled by this plugin
    NotHandled,
    /// Command requires additional input
    NeedsInput(String),
}

/// A command to be executed by a plugin
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VanguardCommand {
    /// The name of the command to execute
    pub name: String,
    /// Arguments passed to the command
    pub args: Vec<String>,
    /// Original command string
    pub original: String,
}

/// Context for command execution
#[derive(Debug, Clone)]
pub struct CommandContext {
    /// Current working directory
    pub cwd: std::path::PathBuf,
    /// Environment variables
    pub env: HashMap<String, String>,
    /// Whether command is running in interactive mode
    pub interactive: bool,
    /// Additional context data
    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(),
        }
    }
}

/// Trait for handling commands
#[async_trait]
pub trait CommandHandler {
    /// Get a list of commands supported by this handler
    fn get_commands(&self) -> Vec<Command>;

    /// Handle a command
    async fn handle_command(
        &self,
        command: &VanguardCommand,
        ctx: &CommandContext,
    ) -> CommandResult;

    /// Check if this handler can handle a command
    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()))
    }
}