cyfs_debug/
debug_config.rs1use 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 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 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}