use crate::domain::DomainError;
use async_trait::async_trait;
use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq)]
pub enum IdeType {
VsCode,
Cursor,
}
impl IdeType {
pub fn command_name(&self) -> &'static str {
match self {
IdeType::VsCode => "code",
IdeType::Cursor => "cursor",
}
}
pub fn display_name(&self) -> &'static str {
match self {
IdeType::VsCode => "VSCode",
IdeType::Cursor => "Cursor",
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum InstallationMethod {
CliCommand { command_path: PathBuf },
FileSystem { extensions_dir: PathBuf },
}
#[derive(Debug, Clone)]
pub struct InstallationStrategy {
pub ide_type: IdeType,
pub method: InstallationMethod,
}
impl InstallationStrategy {
pub fn new(ide_type: IdeType, method: InstallationMethod) -> Self {
Self { ide_type, method }
}
}
#[async_trait]
pub trait InstallationDetector: Send + Sync {
async fn detect_method(&self, ide_type: &IdeType) -> Result<InstallationMethod, DomainError>;
}
#[async_trait]
pub trait InstallationExecutor: Send + Sync {
async fn execute(
&self,
strategy: &InstallationStrategy,
extension_id: &str,
vsix_data: &[u8],
) -> Result<(), DomainError>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ide_type_command_names() {
assert_eq!(IdeType::VsCode.command_name(), "code");
assert_eq!(IdeType::Cursor.command_name(), "cursor");
}
#[test]
fn test_ide_type_display_names() {
assert_eq!(IdeType::VsCode.display_name(), "VSCode");
assert_eq!(IdeType::Cursor.display_name(), "Cursor");
}
#[test]
fn test_installation_strategy_creation() {
let strategy = InstallationStrategy::new(
IdeType::VsCode,
InstallationMethod::CliCommand {
command_path: PathBuf::from("/usr/local/bin/code"),
},
);
assert_eq!(strategy.ide_type, IdeType::VsCode);
match strategy.method {
InstallationMethod::CliCommand { command_path } => {
assert_eq!(command_path, PathBuf::from("/usr/local/bin/code"));
}
_ => panic!("Expected CliCommand"),
}
}
}