cyfs_debug/
debug_config.rs

1use cyfs_base::{BuckyError, BuckyErrorCode, BuckyResult};
2use cyfs_util::get_cyfs_root_path;
3
4use std::path::{Path, PathBuf};
5
6const CONFIG_FILE_NAME: &str = "debug.toml";
7
8pub struct DebugConfigFile {
9    file_name: String,
10    config_path: Option<PathBuf>,
11}
12
13impl DebugConfigFile {
14    pub fn new() -> Self {
15        let mut ret = Self {
16            file_name: CONFIG_FILE_NAME.to_owned(),
17            config_path: None,
18        };
19
20        if let Some(file) = ret.search() {
21            println!("will use debug config file: {}", file.display());
22            ret.config_path = Some(file);
23        }
24
25        ret
26    }
27
28    fn into(self) -> Option<PathBuf> {
29        self.config_path
30    }
31
32    fn search(&self) -> Option<PathBuf> {
33        match std::env::current_exe() {
34            Ok(mut dir) => {
35                dir.set_file_name(&self.file_name);
36
37                if dir.is_file() {
38                    info!("config found: {}", dir.display());
39                    return Some(dir);
40                }
41            }
42            Err(e) => {
43                error!("get current_exe error: {}", e);
44            }
45        };
46
47        match std::env::current_dir() {
48            Ok(mut dir) => {
49                dir.set_file_name(&self.file_name);
50
51                if dir.is_file() {
52                    info!("config found: {}", dir.display());
53                    return Some(dir);
54                }
55            }
56            Err(e) => {
57                error!("get current_exe error: {}", e);
58            }
59        };
60
61        // 从/cyfs/etc/目录下面查找
62        let root = get_cyfs_root_path();
63        let file = root.join(format!("etc/{}", self.file_name));
64        if file.is_file() {
65            info!("config found: {}", file.display());
66            return Some(file);
67        }
68
69        warn!("config not found! now will use default config");
70        return None;
71    }
72}
73
74pub struct DebugConfig {
75    pub config_file: Option<PathBuf>,
76}
77
78impl DebugConfig {
79    pub fn new() -> Self {
80        let config_file = DebugConfigFile::new();
81        Self {
82            config_file: config_file.into(),
83        }
84    }
85
86    pub fn get_config(key: &str) -> Option<&'static toml::Value> {
87        use once_cell::sync::OnceCell;
88        static S_INSTANCE: OnceCell<BuckyResult<toml::value::Table>> = OnceCell::new();
89        let root = S_INSTANCE.get_or_init(|| {
90            let config = DebugConfig::new();
91            config.load()
92        });
93
94        match root {
95            Ok(root) => root.get(key),
96            Err(_) => None,
97        }
98    }
99
100    pub fn set_config_file(&mut self, file: &Path) {
101        self.config_file = Some(file.to_owned());
102    }
103
104    pub fn load(&self) -> BuckyResult<toml::value::Table> {
105        if let Some(file) = &self.config_file {
106            self.load_root(file)
107        } else {
108            println!("config file not found!");
109            Err(BuckyError::from(BuckyErrorCode::NotFound))
110        }
111    }
112
113    fn load_root(&self, config_path: &Path) -> BuckyResult<toml::value::Table> {
114        let contents = std::fs::read_to_string(config_path).map_err(|e| {
115            let msg = format!(
116                "load log config failed! file={}, err={}",
117                config_path.display(),
118                e
119            );
120            error!("{}", msg);
121
122            BuckyError::new(BuckyErrorCode::IoError, msg)
123        })?;
124
125        let cfg_node: toml::Value = toml::from_str(&contents).map_err(|e| {
126            let msg = format!(
127                "parse log config failed! file={}, content={}, err={}",
128                config_path.display(),
129                contents,
130                e
131            );
132            error!("{}", msg);
133
134            BuckyError::new(BuckyErrorCode::InvalidFormat, msg)
135        })?;
136
137        // println!("debug config: {:?}", cfg_node);
138
139        if !cfg_node.is_table() {
140            let msg = format!(
141                "invalid log config format! file={}, content={}",
142                config_path.display(),
143                contents,
144            );
145            error!("{}", msg);
146
147            return Err(BuckyError::new(BuckyErrorCode::InvalidFormat, msg));
148        }
149
150        match cfg_node {
151            toml::Value::Table(v) => Ok(v),
152            _ => unreachable!(),
153        }
154    }
155}