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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use cyfs_base::{BuckyError, BuckyErrorCode, BuckyResult};
use cyfs_util::get_cyfs_root_path;
use std::path::{Path, PathBuf};
const CONFIG_FILE_NAME: &str = "debug.toml";
pub struct DebugConfigFile {
file_name: String,
config_path: Option<PathBuf>,
}
impl DebugConfigFile {
pub fn new() -> Self {
let mut ret = Self {
file_name: CONFIG_FILE_NAME.to_owned(),
config_path: None,
};
if let Some(file) = ret.search() {
println!("will use debug config file: {}", file.display());
ret.config_path = Some(file);
}
ret
}
fn into(self) -> Option<PathBuf> {
self.config_path
}
fn search(&self) -> Option<PathBuf> {
match std::env::current_exe() {
Ok(mut dir) => {
dir.set_file_name(&self.file_name);
if dir.is_file() {
info!("config found: {}", dir.display());
return Some(dir);
}
}
Err(e) => {
error!("get current_exe error: {}", e);
}
};
match std::env::current_dir() {
Ok(mut dir) => {
dir.set_file_name(&self.file_name);
if dir.is_file() {
info!("config found: {}", dir.display());
return Some(dir);
}
}
Err(e) => {
error!("get current_exe error: {}", e);
}
};
let root = get_cyfs_root_path();
let file = root.join(format!("etc/{}", self.file_name));
if file.is_file() {
info!("config found: {}", file.display());
return Some(file);
}
warn!("config not found! now will use default config");
return None;
}
}
pub struct DebugConfig {
pub config_file: Option<PathBuf>,
}
impl DebugConfig {
pub fn new() -> Self {
let config_file = DebugConfigFile::new();
Self {
config_file: config_file.into(),
}
}
pub fn get_config(key: &str) -> Option<&'static toml::Value> {
use once_cell::sync::OnceCell;
static S_INSTANCE: OnceCell<BuckyResult<toml::value::Table>> = OnceCell::new();
let root = S_INSTANCE.get_or_init(|| {
let config = DebugConfig::new();
config.load()
});
match root {
Ok(root) => root.get(key),
Err(_) => None,
}
}
pub fn set_config_file(&mut self, file: &Path) {
self.config_file = Some(file.to_owned());
}
pub fn load(&self) -> BuckyResult<toml::value::Table> {
if let Some(file) = &self.config_file {
self.load_root(file)
} else {
println!("config file not found!");
Err(BuckyError::from(BuckyErrorCode::NotFound))
}
}
fn load_root(&self, config_path: &Path) -> BuckyResult<toml::value::Table> {
let contents = std::fs::read_to_string(config_path).map_err(|e| {
let msg = format!(
"load log config failed! file={}, err={}",
config_path.display(),
e
);
error!("{}", msg);
BuckyError::new(BuckyErrorCode::IoError, msg)
})?;
let cfg_node: toml::Value = toml::from_str(&contents).map_err(|e| {
let msg = format!(
"parse log config failed! file={}, content={}, err={}",
config_path.display(),
contents,
e
);
error!("{}", msg);
BuckyError::new(BuckyErrorCode::InvalidFormat, msg)
})?;
if !cfg_node.is_table() {
let msg = format!(
"invalid log config format! file={}, content={}",
config_path.display(),
contents,
);
error!("{}", msg);
return Err(BuckyError::new(BuckyErrorCode::InvalidFormat, msg));
}
match cfg_node {
toml::Value::Table(v) => Ok(v),
_ => unreachable!(),
}
}
}