1use anyhow::Result;
8use std::path::{Path, PathBuf};
9
10pub mod config;
11pub mod manager;
12pub mod resolver;
13
14pub use config::PathConfig;
15pub use manager::PathManager;
16pub use resolver::PathResolver;
17
18#[derive(Debug, Clone)]
20pub struct VxPaths {
21 pub base_dir: PathBuf,
23 pub tools_dir: PathBuf,
25 pub cache_dir: PathBuf,
27 pub config_dir: PathBuf,
29 pub tmp_dir: PathBuf,
31}
32
33impl VxPaths {
34 pub fn new() -> Result<Self> {
36 let home_dir = dirs::home_dir()
37 .ok_or_else(|| anyhow::anyhow!("Could not determine home directory"))?;
38
39 let base_dir = home_dir.join(".vx");
40
41 Ok(Self {
42 tools_dir: base_dir.join("tools"),
43 cache_dir: base_dir.join("cache"),
44 config_dir: base_dir.join("config"),
45 tmp_dir: base_dir.join("tmp"),
46 base_dir,
47 })
48 }
49
50 pub fn with_base_dir<P: AsRef<Path>>(base_dir: P) -> Self {
52 let base_dir = base_dir.as_ref().to_path_buf();
53
54 Self {
55 tools_dir: base_dir.join("tools"),
56 cache_dir: base_dir.join("cache"),
57 config_dir: base_dir.join("config"),
58 tmp_dir: base_dir.join("tmp"),
59 base_dir,
60 }
61 }
62
63 pub fn ensure_dirs(&self) -> Result<()> {
65 std::fs::create_dir_all(&self.base_dir)?;
66 std::fs::create_dir_all(&self.tools_dir)?;
67 std::fs::create_dir_all(&self.cache_dir)?;
68 std::fs::create_dir_all(&self.config_dir)?;
69 std::fs::create_dir_all(&self.tmp_dir)?;
70 Ok(())
71 }
72}
73
74impl Default for VxPaths {
75 fn default() -> Self {
76 Self::new().unwrap_or_else(|_| {
77 Self::with_base_dir(".vx")
79 })
80 }
81}
82
83pub fn executable_extension() -> &'static str {
85 if cfg!(target_os = "windows") {
86 ".exe"
87 } else {
88 ""
89 }
90}
91
92pub fn with_executable_extension(tool_name: &str) -> String {
94 format!("{}{}", tool_name, executable_extension())
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 #[test]
102 fn test_vx_paths_creation() {
103 let paths = VxPaths::with_base_dir("/tmp/test-vx");
104
105 assert_eq!(paths.base_dir, PathBuf::from("/tmp/test-vx"));
106 assert_eq!(paths.tools_dir, PathBuf::from("/tmp/test-vx/tools"));
107 assert_eq!(paths.cache_dir, PathBuf::from("/tmp/test-vx/cache"));
108 assert_eq!(paths.config_dir, PathBuf::from("/tmp/test-vx/config"));
109 assert_eq!(paths.tmp_dir, PathBuf::from("/tmp/test-vx/tmp"));
110 }
111
112 #[test]
113 fn test_executable_extension() {
114 if cfg!(target_os = "windows") {
115 assert_eq!(executable_extension(), ".exe");
116 assert_eq!(with_executable_extension("node"), "node.exe");
117 } else {
118 assert_eq!(executable_extension(), "");
119 assert_eq!(with_executable_extension("node"), "node");
120 }
121 }
122}