Skip to main content

vsix/domain/
installation_strategy.rs

1use crate::domain::DomainError;
2use async_trait::async_trait;
3use std::path::PathBuf;
4
5/// Represents the available IDE types for extension installation
6#[derive(Debug, Clone, PartialEq)]
7pub enum IdeType {
8    VsCode,
9    Cursor,
10}
11
12impl IdeType {
13    /// Returns the CLI command name for the IDE
14    pub fn command_name(&self) -> &'static str {
15        match self {
16            IdeType::VsCode => "code",
17            IdeType::Cursor => "cursor",
18        }
19    }
20
21    /// Returns the display name for the IDE
22    pub fn display_name(&self) -> &'static str {
23        match self {
24            IdeType::VsCode => "VSCode",
25            IdeType::Cursor => "Cursor",
26        }
27    }
28}
29
30/// Represents the installation method available for an IDE
31#[derive(Debug, Clone, PartialEq)]
32pub enum InstallationMethod {
33    /// Install using CLI command (e.g., `code --install-extension`)
34    CliCommand { command_path: PathBuf },
35    /// Install by extracting to file system directory
36    FileSystem { extensions_dir: PathBuf },
37}
38
39/// Value object representing an installation strategy for a specific IDE
40#[derive(Debug, Clone)]
41pub struct InstallationStrategy {
42    pub ide_type: IdeType,
43    pub method: InstallationMethod,
44}
45
46impl InstallationStrategy {
47    pub fn new(ide_type: IdeType, method: InstallationMethod) -> Self {
48        Self { ide_type, method }
49    }
50}
51
52/// Service for detecting available installation methods
53#[async_trait]
54pub trait InstallationDetector: Send + Sync {
55    /// Detects the available installation method for the specified IDE
56    async fn detect_method(&self, ide_type: &IdeType) -> Result<InstallationMethod, DomainError>;
57}
58
59/// Service for executing installations using a specific strategy
60#[async_trait]
61pub trait InstallationExecutor: Send + Sync {
62    /// Executes the installation using the provided strategy
63    async fn execute(
64        &self,
65        strategy: &InstallationStrategy,
66        extension_id: &str,
67        vsix_data: &[u8],
68    ) -> Result<(), DomainError>;
69}
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74
75    #[test]
76    fn test_ide_type_command_names() {
77        assert_eq!(IdeType::VsCode.command_name(), "code");
78        assert_eq!(IdeType::Cursor.command_name(), "cursor");
79    }
80
81    #[test]
82    fn test_ide_type_display_names() {
83        assert_eq!(IdeType::VsCode.display_name(), "VSCode");
84        assert_eq!(IdeType::Cursor.display_name(), "Cursor");
85    }
86
87    #[test]
88    fn test_installation_strategy_creation() {
89        let strategy = InstallationStrategy::new(
90            IdeType::VsCode,
91            InstallationMethod::CliCommand {
92                command_path: PathBuf::from("/usr/local/bin/code"),
93            },
94        );
95
96        assert_eq!(strategy.ide_type, IdeType::VsCode);
97        match strategy.method {
98            InstallationMethod::CliCommand { command_path } => {
99                assert_eq!(command_path, PathBuf::from("/usr/local/bin/code"));
100            }
101            _ => panic!("Expected CliCommand"),
102        }
103    }
104}