头图

Working with configuration files is a normal part of application development. Mature development languages have their own way of dealing with configuration files. golang has mature third-party libraries like viper to handle configuration files. Rust's third-party libraries are immature.

In this article we will talk about how rust handles configuration files.

Process for processing yaml configuration files

The role of the configuration file is a series of switches for the corresponding functions of the application. Configured before the application starts, loaded when the application starts, ready for use at runtime.

We still use interactcli-rs as an example to illustrate the processing of configuration files.

The main logic for parsing configuration files is in the src/configure directory.

Define the config structure

First, define a structure to carry configuration items. Since the Config struct needs to interact with the yaml file, we define a structure with serialization and deserialization capabilities.

 #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct Config {
    pub server: String,
    pub token: String,
}

Define the necessary functionality for the Config structure

 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(())
    }
}

Use lazy_static to initialize the configuration item singleton

 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
    });
}

load configuration file

interactcli-rs is a command line program. The strategy for loading the configuration file is: when the location of the configuration file is specified, the configuration is loaded according to the given path; if the configuration file is not specified, it is loaded according to the default path, and the program is terminated if the default configuration file does not exist.

The cmd_match function in src/cmd/rootcmd.rs contains the above logic.

 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("");
    }
    ......

postscript

Manually processing configuration files is still rather cumbersome. Especially in the writing of the configuration file, each configuration item must be clearly configured, even if the configuration item is empty, it needs to be filled in. In order to ensure that the configuration items of the configuration file are complete, we define the flush_to_file function for the Config struct to generate the configuration file.

Since the ecology of rust is still younger than that of golang and java, the third-party toolkit is not as complete as the two. The processing of configuration files is cumbersome, and manual processing is required in many places, but the requirements have been basically met.

See you next time.

Author: Jia Shiwen


京东云开发者
3.3k 声望5.4k 粉丝

京东云开发者(Developer of JD Technology)是京东云旗下为AI、云计算、IoT等相关领域开发者提供技术分享交流的平台。