解决配置文件是利用开发的惯例操作。成熟的开发语言都有本人解决配置文件的套路。golang 有 viper 这样的成熟第三方库来解决配置文件。rust 的第三方库并不成熟。
这篇文章咱们来聊聊 rust 如何解决配置文件。
解决 yaml 配置文件的流程
配置文件的作用是一系列应用程序相应性能的开关。在利用启动前配置,利用启动时加载,以备运行时应用。
咱们仍旧用 interactcli-rs 为例,阐明一下配置文件的处理过程。
解析配置文件的次要逻辑在 src/configure 目录。
定义 config 构造体
首先,定义一个构造体用来承载配置项。因为 Config struct 须要与 yaml 文件交互,咱们定义一个具备序列化与反序列化能力的构造体。
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct Config {
pub server: String,
pub token: String,
}
为 Config 构造体定义必要的性能
impl Config {pub fn default() -> Self {
Self {server: "http://127.0.0.1:8080".to_string(),
token: "".to_string(),}
}
pub fn set_self(&mut self, config: Config) {
self.server = config.server;
self.token = config.token;
}
pub fn get_config_image(&self) -> Self {self.clone()
}
pub fn flush_to_file(&self, path: String) -> Result<()> {let yml = serde_yaml::to_string(&self)?;
fs::write(path, yml)?;
Ok(())
}
}
利用 lazy_static 初始化配置项单例
lazy_static::lazy_static! {
static ref GLOBAL_CONFIG: Mutex<Config> = {let global_config = Config::default();
Mutex::new(global_config)
};
static ref CONFIG_FILE_PATH: RwLock<String> = RwLock::new({let path = "".to_string();
path
});
}
加载配置文件
interactcli-rs 是一个命令行程序。加载配置文件的策略为:当指定配置文件地位时,则按给定门路加载配置;如果未指定配置文件则依照默认门路加载,此时若默认配置文件不存在则终止程序。
src/cmd/rootcmd.rs 中的 cmd_match 函数蕴含下面的逻辑。
fn cmd_match(matches: &ArgMatches) {if let Some(c) = matches.value_of("config") {set_config_file_path(c.to_string());
set_config_from_file(&get_config_file_path());
} else {set_config_from_file("");
}
......
后记
手工解决配置文件还是比拟繁琐。尤其在配置文件的书写上,必须明确配置每一个配置项,即便配置项为空也需填写。为了保障配置文件的配置项齐全,咱们为 Config struct 定义了 flush_to_file 函数,用来生成配置文件。
因为 rust 的生态较 golang 以及 java 的生态还很年老,第三方的工具包不迭两者欠缺。在配置文件的解决上比拟繁琐,很多中央须要手工解决,然而已根本满足要求。
咱们下期见。
作者:贾世闻