1use crate::error::Result;
2use anyhow::Context;
3use std::path::{Path, PathBuf};
4
5pub fn get_absolute_path<P: AsRef<Path>>(path: P) -> Result<PathBuf> {
7 let path = path.as_ref();
8 std::fs::canonicalize(path).with_context(|| format!("无法解析路径: {:?}", path))
9}
10
11pub fn get_home_dir() -> Result<PathBuf> {
13 dirs::home_dir().context("无法获取用户主目录")
14}
15
16pub fn is_file_exists<P: AsRef<Path>>(path: P) -> bool {
18 path.as_ref().is_file()
19}
20
21pub fn cache_dir(app_name: &str) -> Result<PathBuf> {
30 let base = if cfg!(target_os = "macos") {
31 dirs::home_dir()
32 .map(|h| h.join("Library").join("Caches"))
33 .context("无法获取 macOS 缓存目录")
34 } else if cfg!(target_os = "windows") {
35 std::env::var("LOCALAPPDATA")
36 .map(PathBuf::from)
37 .or_else(|_| {
38 dirs::home_dir()
39 .map(|h| h.join("AppData").join("Local"))
40 .ok_or(std::env::VarError::NotPresent)
41 })
42 .map(|p| p.join(app_name).join("cache"))
43 .context("无法获取 Windows 缓存目录")
44 } else {
45 std::env::var("XDG_CACHE_HOME")
47 .map(PathBuf::from)
48 .or_else(|_| {
49 dirs::home_dir()
50 .map(|h| h.join(".cache"))
51 .ok_or(std::env::VarError::NotPresent)
52 })
53 .context("无法获取缓存目录")
54 }?;
55
56 let dir = if cfg!(target_os = "macos") || cfg!(not(target_os = "windows")) {
57 base.join(app_name)
58 } else {
59 base
60 };
61
62 std::fs::create_dir_all(&dir).with_context(|| format!("创建缓存目录失败: {:?}", dir))?;
63 Ok(dir)
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn test_get_home_dir() {
72 let home = get_home_dir().expect("home dir 应可解析");
73 assert!(home.is_absolute());
74 assert!(home.exists());
75 }
76
77 #[test]
78 fn test_get_absolute_path_preserves_suffix() {
79 let me = concat!(env!("CARGO_MANIFEST_DIR"), "/src/path.rs");
81 let abs = get_absolute_path(me).expect("当前文件应存在且可解析");
82 assert!(abs.ends_with("path.rs"));
83 }
84
85 #[test]
86 fn test_is_file_exists() {
87 let me = concat!(env!("CARGO_MANIFEST_DIR"), "/src/path.rs");
88 assert!(is_file_exists(me));
89 assert!(!is_file_exists("/nonexistent/definitely/missing"));
90 }
91}