knife_util/
path.rs

1//! 路径工具模块
2//!
3//! 提供工作目录检测和路径处理功能
4
5use crate::error::AppError;
6use std::env;
7use std::path::PathBuf;
8
9/// 获取工作目录路径
10///
11/// 根据环境自动判断工作目录:
12/// - 开发环境:使用 `workspace` 目录(测试时使用 `workspace/test`)
13/// - 生产环境:使用可执行文件所在目录
14///
15/// # 示例
16/// ```rust
17/// use knife_util::get_work_dir;
18///
19/// fn main() -> Result<(), knife_util::AppError> {
20///     let work_dir = get_work_dir()?;
21///     println!("工作目录: {:?}", work_dir);
22///     Ok(())
23/// }
24/// ```
25pub fn get_work_dir() -> Result<PathBuf, AppError> {
26    if is_dev_mode() {
27        // 在开发环境中,使用Cargo清单目录
28        if let Ok(manifest_dir) = env::var("CARGO_MANIFEST_DIR") {
29            let manifest_path = PathBuf::from(manifest_dir);
30
31            // 验证路径是否存在且为目录
32            if manifest_path.exists() && manifest_path.is_dir() {
33                let workspace_path = if cfg!(test) {
34                    manifest_path.join("workspace").join("test")
35                } else {
36                    manifest_path.join("workspace")
37                };
38                return Ok(workspace_path);
39            }
40        }
41    }
42
43    // 在生产环境中,尝试获取可执行文件路径
44    if let Ok(exe_path) = env::current_exe()
45        && let Some(parent) = exe_path.parent()
46    {
47        // 检查可执行文件是否在bin或sbin目录中,如果是则使用上级目录
48        if let Some(parent_name) = parent.file_name()
49            && (parent_name == "bin" || parent_name == "sbin")
50            && let Some(grandparent) = parent.parent()
51        {
52            return Ok(grandparent.to_path_buf());
53        }
54        // 否则使用可执行文件所在路径
55        return Ok(parent.to_path_buf());
56    }
57
58    Err(AppError::new("GET_WORK_DIR_ERROR", "无法获取工作目录"))
59}
60
61/// 检查是否为开发模式
62///
63/// 通过检查CARGO_MANIFEST_DIR环境变量判断
64///
65/// # 示例
66/// ```rust
67/// use knife_util::is_dev_mode;
68///
69/// if is_dev_mode() {
70///     println!("当前在开发模式中");
71/// } else {
72///     println!("当前在生产模式中");
73/// }
74/// ```
75pub fn is_dev_mode() -> bool {
76    env::var("CARGO_MANIFEST_DIR").is_ok()
77}
78
79/// 构建工作路径
80///
81/// 基于工作目录构建指定路径
82///
83/// # 示例
84/// ```rust
85/// use knife_util::build_work_path;
86///
87/// fn main() -> Result<(), knife_util::AppError> {
88///     let config_path = build_work_path("config/app.toml")?;
89///     println!("配置文件路径: {:?}", config_path);
90///     Ok(())
91/// }
92/// ```
93pub fn build_work_path(path: &str) -> Result<PathBuf, AppError> {
94    let work_dir = get_work_dir()?;
95    Ok(work_dir.join(path))
96}