xref: /NovaShell/src/env.rs (revision dcc611d712e5611c796226bef3694bd991c34356)
1 use std::{
2     collections::HashMap,
3     fs::File,
4     io::{Read, Write},
5     path::Path,
6     string::String,
7     vec::Vec,
8 };
9 
10 pub const ROOT_PATH: &str = "/";
11 pub const ENV_FILE_PATH: &str = "/etc/profile";
12 
13 pub struct Env(std::collections::HashMap<String, String>);
14 
15 lazy_static! {
16     static ref ENV: std::sync::Mutex<Env> = std::sync::Mutex::new(Env(HashMap::new()));
17 }
18 
19 impl Env {
20     /// 初始化环境变量文件
21     pub fn init_envfile() {
22         let mut file = File::create(ENV_FILE_PATH).unwrap();
23         file.write_all("PATH=/bin:/usr/bin:/usr/local/bin\n".as_bytes())
24             .unwrap();
25         file.write_all("PWD=/\n".as_bytes()).unwrap();
26     }
27 
28     /// 读取环境变量文件
29     /// 如果文件不存在则创建
30     pub fn read_env() {
31         let mut env = ENV.lock().unwrap();
32         if !Path::new(ENV_FILE_PATH).exists() {
33             Env::init_envfile();
34         }
35         let mut file = File::open(ENV_FILE_PATH).unwrap();
36         let mut buf: Vec<u8> = Vec::new();
37         file.read_to_end(&mut buf).unwrap();
38         for (name, value) in String::from_utf8(buf)
39             .unwrap()
40             .split('\n')
41             .filter_map(|str| {
42                 let v = str.split('=').collect::<Vec<&str>>();
43                 if v.len() == 2 && !v.contains(&"") {
44                     Some((*v.get(0).unwrap(), *v.get(1).unwrap()))
45                 } else {
46                     None
47                 }
48             })
49             .collect::<Vec<(&str, &str)>>()
50         {
51             env.0.insert(String::from(name), String::from(value));
52         }
53     }
54 
55     pub fn get(key: &String) -> Option<String> {
56         let env = &mut ENV.lock().unwrap().0;
57         env.get(key).map(|value| value.clone())
58     }
59 
60     pub fn insert(key: String, value: String) {
61         ENV.lock().unwrap().0.insert(key, value);
62     }
63 
64     pub fn path() -> Vec<String> {
65         let env = &ENV.lock().unwrap().0;
66         let paths = env.get("PATH").unwrap();
67         paths
68             .split(':')
69             .filter_map(|str| {
70                 let path = String::from(str);
71                 if Path::new(&path).is_dir() {
72                     Some(path)
73                 } else {
74                     None
75                 }
76             })
77             .collect::<Vec<String>>()
78     }
79 }
80