1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use crate::Error;
use crate::Result;
use std::env::var;
use std::path::PathBuf;
use std::{env, path::Path};

/// 环境变量,初始目录
pub static ORIGINAL_DIR: &'static str = "ORIGINAL_DIR";

/// 添加环境变量到系统目录
/// 兼容linux与windows
pub fn add_system_path<P>(directory: P) -> Result<()>
where
  P: AsRef<Path>,
{
  // Windows使用;,而Unix-like系统使用:
  let path_separator = if cfg!(windows) { ';' } else { ':' };
  // 获取当前的环境变量值
  let mut path = match env::var("PATH") {
    Ok(path) => path,
    Err(_) => String::new(),
  };
  // 路径确保不存在
  let directory_str = directory
    .as_ref()
    .to_str()
    .ok_or(Error::Option("add_system_path 解析路径出错".into()))?
    .to_string();
  // 不能为空
  if directory_str.is_empty() || path.is_empty() {
    return Err(Error::Empty);
  }
  let new_path = format!("{}{}", &directory_str, path_separator);
  // 路径已经存在
  if path.contains(&new_path) {
    return Err(Error::Exists(new_path.into()));
  }
  path.push_str(&new_path);
  // 设置新的PATH环境变量
  env::set_var("PATH", path);

  Ok(())
}

/// 变量追加路径
/// # Example
/// ```rust
/// let p:Path = env_path_join(HCNET_LIB_ENV,HCPLAY_CORE_LIB).unwrap();
/// ```
pub fn env_path_join(variable: &str, add: &str) -> Result<PathBuf> {
  let var_path = Path::new(&var(variable)?).to_path_buf();
  if var_path.exists() {
    let target = var_path.join(add);
    if target.exists() {
      Ok(target)
    } else {
      Err(Error::NotFound(target.to_string_lossy().to_string().into()))
    }
  } else {
    Err(Error::NotFound(
      var_path.to_string_lossy().to_string().into(),
    ))
  }
}

/// 初始化原始路径
pub fn init_original_dir() -> Result<PathBuf> {
  // 获取当前工作目录
  let current_dir = env::current_dir()?;
  // 设置环境变量来保存原始目录
  env::set_var(ORIGINAL_DIR, current_dir.clone());
  Ok(current_dir)
}
/// 恢复原始路径
pub fn reset_original_dir() -> Result<PathBuf> {
  let res = get_original_dir()?;
  env::set_current_dir(res.clone())?;
  Ok(res)
}
/// 获取初始目录
pub fn get_original_dir() -> Result<PathBuf> {
  env::var_os(ORIGINAL_DIR)
    .and_then(|x| Some(Path::new(&x).to_path_buf()))
    .ok_or("无法读取ORIGINAL_DIR变量".into())
}