use std::path::Path; use std::path::PathBuf; use std::env; use std::process::Command; use anyhow::{Result, Error}; #[derive(Debug, Clone, PartialEq)] pub enum BackendType { Nfs4, Fskit, } impl BackendType { pub fn name(&self) -> &'static str { match self { BackendType::Nfs4 => "nfs", BackendType::Fskit => "fskit", } } pub fn supports_macos_version(&self, version: &str) -> bool { match self { BackendType::Nfs4 => true, BackendType::Fskit => version.starts_with("26"), } } } pub fn detect_macos_version() -> String { env::var("MACOS_VERSION").unwrap_or_else(|_| { let output = Command::new("sw_vers") .arg("-productVersion") .output() .expect("Failed to get macOS version"); String::from_utf8_lossy(&output.stdout).trim().to_string() }) } pub fn select_backend() -> BackendType { let version = detect_macos_version(); if version.starts_with("26") { BackendType::Fskit } else { BackendType::Nfs4 } } pub fn select_backend_manual(backend_name: &str) -> Result { match backend_name { "nfs" | "nfs4" => Ok(BackendType::Nfs4), "fskit" => Ok(BackendType::Fskit), _ => Err(Error::msg(format!("Unknown backend: {}", backend_name))), } } pub fn detect_fuse_t_binary() -> bool { Path::new("/Library/Application Support/fuse-t/bin/go-nfsv4").exists() } pub fn get_fuse_t_path() -> Option { if detect_fuse_t_binary() { Some(PathBuf::from("/Library/Application Support/fuse-t/bin/go-nfsv4")) } else { None } } #[cfg(test)] mod tests { use super::*; #[test] fn test_backend_type_name() { assert_eq!(BackendType::Nfs4.name(), "nfs"); assert_eq!(BackendType::Fskit.name(), "fskit"); } #[test] fn test_backend_support() { assert!(BackendType::Nfs4.supports_macos_version("25.0")); assert!(BackendType::Nfs4.supports_macos_version("26.0")); assert!(!BackendType::Fskit.supports_macos_version("25.0")); assert!(BackendType::Fskit.supports_macos_version("26.0")); } #[test] fn test_select_backend_macos_26() { env::set_var("MACOS_VERSION", "26.4.1"); let backend = select_backend(); assert_eq!(backend, BackendType::Fskit); env::remove_var("MACOS_VERSION"); } #[test] fn test_select_backend_macos_25() { env::set_var("MACOS_VERSION", "25.0.0"); let backend = select_backend(); assert_eq!(backend, BackendType::Nfs4); env::remove_var("MACOS_VERSION"); } #[test] fn test_manual_backend_selection() { assert!(select_backend_manual("nfs").is_ok()); assert!(select_backend_manual("fskit").is_ok()); assert!(select_backend_manual("invalid").is_err()); } #[test] fn test_fuse_t_binary_detection() { // Should detect FUSE-T binary after installation let detected = detect_fuse_t_binary(); assert!(detected); // Expected to be true after installation } }