thoughts_tool/mount/
manager.rs1use super::types::{MountInfo, MountOptions};
2use crate::error::Result;
3use crate::platform::{Platform, PlatformInfo};
4use async_trait::async_trait;
5use std::path::{Path, PathBuf};
6
7#[cfg(target_os = "linux")]
8use super::mergerfs::MergerfsManager;
9
10#[cfg(target_os = "macos")]
11use super::fuse_t::FuseTManager;
12
13#[async_trait]
15pub trait MountManager: Send + Sync {
16 async fn mount(&self, sources: &[PathBuf], target: &Path, options: &MountOptions)
18 -> Result<()>;
19
20 async fn unmount(&self, target: &Path, force: bool) -> Result<()>;
22
23 async fn is_mounted(&self, target: &Path) -> Result<bool>;
25
26 async fn list_mounts(&self) -> Result<Vec<MountInfo>>;
28
29 async fn get_mount_info(&self, target: &Path) -> Result<Option<MountInfo>>;
31
32 async fn check_health(&self) -> Result<()>;
34
35 fn get_mount_command(
37 &self,
38 sources: &[PathBuf],
39 target: &Path,
40 options: &MountOptions,
41 ) -> String;
42}
43
44pub fn get_mount_manager(platform_info: &PlatformInfo) -> Result<Box<dyn MountManager>> {
46 match &platform_info.platform {
47 #[cfg(target_os = "linux")]
48 Platform::Linux(info) => {
49 if !info.has_mergerfs {
50 return Err(crate::error::ThoughtsError::ToolNotFound {
51 tool: "mergerfs".to_string(),
52 });
53 }
54 if !info.fuse_available {
55 return Err(crate::error::ThoughtsError::PlatformNotSupported {
56 platform: "Linux without FUSE support".to_string(),
57 });
58 }
59 Ok(Box::new(MergerfsManager::new(info.clone())))
60 }
61 #[cfg(target_os = "macos")]
62 Platform::MacOS(info) => {
63 if !info.has_fuse_t && !info.has_macfuse {
64 return Err(crate::error::ThoughtsError::ToolNotFound {
65 tool: "FUSE-T or macFUSE".to_string(),
66 });
67 }
68 Ok(Box::new(FuseTManager::new(info.clone())))
69 }
70 #[cfg(not(target_os = "linux"))]
71 Platform::Linux(_) => Err(crate::error::ThoughtsError::PlatformNotSupported {
72 platform: "Linux support not compiled in".to_string(),
73 }),
74 #[cfg(not(target_os = "macos"))]
75 Platform::MacOS(_) => Err(crate::error::ThoughtsError::PlatformNotSupported {
76 platform: "macOS support not compiled in".to_string(),
77 }),
78 Platform::Unsupported(os) => Err(crate::error::ThoughtsError::PlatformNotSupported {
79 platform: os.clone(),
80 }),
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 #[cfg(any(target_os = "linux", target_os = "macos"))]
87 use super::get_mount_manager;
88 #[cfg(target_os = "linux")]
89 use crate::platform::detector::LinuxInfo;
90 #[cfg(target_os = "macos")]
91 use crate::platform::detector::MacOSInfo;
92 #[cfg(any(target_os = "linux", target_os = "macos"))]
93 use crate::platform::{Platform, PlatformInfo};
94 #[cfg(any(target_os = "linux", target_os = "macos"))]
95 use std::path::PathBuf;
96
97 #[test]
98 #[cfg(target_os = "linux")]
99 fn test_get_mount_manager_linux() {
100 let platform_info = PlatformInfo {
101 platform: Platform::Linux(LinuxInfo {
102 distro: "Ubuntu".to_string(),
103 version: "22.04".to_string(),
104 has_mergerfs: true,
105 mergerfs_version: Some("2.33.5".to_string()),
106 fuse_available: true,
107 has_fusermount: false, mergerfs_path: None,
109 fusermount_path: None,
110 }),
111 arch: "x86_64".to_string(),
112 };
113
114 let manager = get_mount_manager(&platform_info);
115 assert!(manager.is_ok());
116 }
117
118 #[test]
119 #[cfg(target_os = "linux")]
120 fn test_get_mount_manager_missing_tools() {
121 let platform_info = PlatformInfo {
122 platform: Platform::Linux(LinuxInfo {
123 distro: "Ubuntu".to_string(),
124 version: "22.04".to_string(),
125 has_mergerfs: false,
126 mergerfs_version: None,
127 fuse_available: true,
128 has_fusermount: true, mergerfs_path: None,
130 fusermount_path: Some(PathBuf::from("/bin/fusermount")),
131 }),
132 arch: "x86_64".to_string(),
133 };
134
135 let result = get_mount_manager(&platform_info);
136 assert!(result.is_err());
137 if let Err(e) = result {
138 match e {
139 crate::error::ThoughtsError::ToolNotFound { tool } => {
140 assert_eq!(tool, "mergerfs");
141 }
142 _ => panic!("Expected ToolNotFound error"),
143 }
144 }
145 }
146
147 #[test]
148 #[cfg(target_os = "macos")]
149 fn test_get_mount_manager_macos() {
150 let platform_info = PlatformInfo {
151 platform: Platform::MacOS(MacOSInfo {
152 version: "14.0".to_string(),
153 has_fuse_t: true,
154 fuse_t_version: Some("1.0.0".to_string()),
155 has_macfuse: false,
156 macfuse_version: None,
157 has_unionfs: true,
158 unionfs_path: Some(PathBuf::from("/usr/local/bin/unionfs-fuse")),
159 }),
160 arch: "aarch64".to_string(),
161 };
162
163 let manager = get_mount_manager(&platform_info);
164 assert!(manager.is_ok());
165 }
166
167 #[test]
168 #[cfg(target_os = "macos")]
169 fn test_get_mount_manager_no_fuse() {
170 let platform_info = PlatformInfo {
171 platform: Platform::MacOS(MacOSInfo {
172 version: "14.0".to_string(),
173 has_fuse_t: false,
174 fuse_t_version: None,
175 has_macfuse: false,
176 macfuse_version: None,
177 has_unionfs: false,
178 unionfs_path: None,
179 }),
180 arch: "aarch64".to_string(),
181 };
182
183 let result = get_mount_manager(&platform_info);
184 assert!(result.is_err());
185 if let Err(e) = result {
186 match e {
187 crate::error::ThoughtsError::ToolNotFound { tool } => {
188 assert_eq!(tool, "FUSE-T or macFUSE");
189 }
190 _ => panic!("Expected ToolNotFound error"),
191 }
192 }
193 }
194}