文盤 Rust -- 配置文件解析

處理配置文件是應用開發的常規操作。成熟的開發語言都有自己處理配置文件的套路。golang 有 viper 這樣的成熟第三方庫來處理配置文件。rust 的第三方庫並不成熟。

這篇文章我們來聊聊 rust 如何處理配置文件。

處理 yaml 配置文件的流程

配置文件的作用是一系列應用程序相應功能的開關。在應用啓動前配置,應用啓動時加載,以備運行時使用。

我們依舊用 interactcli-rs 爲例,說明一下配置文件的處理過程。

解析配置文件的主要邏輯在 src/configure 目錄。

首先,定義一個結構體用來承載配置項。由於 Config struct 需要與 yaml 文件交互,我們定義一個具備序列化與反序列化能力的結構體。

```rust
#[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](https://github.com/jiashiwen/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 的生態還很年輕,第三方的工具包不及兩者完善。在配置文件的處理上比較繁瑣,很多地方需要手工處理,但是已基本滿足要求。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/0FgQ-nUZn-p3UD7qMCwY2w