#configuration #source

覆盖

一个简单的特质,定义了如何通过其他类型覆盖类型。主要用于从不同的来源创建应用程序配置。

2 个不稳定版本

0.2.0 2022年10月9日
0.1.0 2022年8月11日

#19 in #来源

MIT/Apache

8KB
54

Build

覆盖

一个简单的特质,定义了如何通过其他类型覆盖类型。主要用于从不同的来源创建应用程序配置。

示例

use overwrite::Overwrite;

struct Config {
    url: String,
    user: String,
    api_token: String,
}

impl Default for Config {
    fn default() -> Self {
        Self {
            url: "default".to_owned(),
            user: "default".to_owned(),
            api_token: "default".to_owned(),
        }
    }
}

struct CliArgs {
    url: Option<String>,
    user: Option<String>,
    api_token: Option<String>
}

impl Overwrite<CliArgs> for Config {
    fn overwrite_mut(&mut self, cli_args: CliArgs) -> &mut Self {
        // There is a blanket impl to overwrite values with Options.
        // Overwrite happens if the Option is Some.
        self.url.overwrite_mut(cli_args.url);
        self.user.overwrite_mut(cli_args.user);
        self.api_token.overwrite_mut(cli_args.api_token);
        self
    }
}

struct ConfFile {
    url: Option<String>,
    user: Option<String>,
    api_token: Option<String>,
}

impl Overwrite<ConfFile> for Config {
    fn overwrite_mut(&mut self, conf_file: ConfFile) -> &mut Self {
        self.url.overwrite_mut(conf_file.url);
        self.user.overwrite_mut(conf_file.user);
        self.api_token.overwrite_mut(conf_file.api_token);
        self
    }
}

struct EnvVars {
    url: Option<String>,
    user: Option<String>,
    api_token: Option<String>,
}

impl Overwrite<EnvVars> for Config {
    fn overwrite_mut(&mut self, env_vars: EnvVars) -> &mut Self {
        self.url.overwrite_mut(env_vars.url);
        self.user.overwrite_mut(env_vars.user);
        self.api_token.overwrite_mut(env_vars.api_token);
        self
    }
}

fn main() {
    let cli_args = parse_args();
    let conf_file = read_conf_file();
    let env_vars = parse_env();

    // Note the precedense. `cli_args` have the highest precedense while default config values
    // have the lowest precedense. `conf_file` values will be overwritten by `env_vars` if env
    // vars are present.
    let config = Config::default()
        .overwrite(conf_file)
        .overwrite(env_vars)
        .overwrite(cli_args);

    assert_eq!(config.url, "default");
    assert_eq!(config.user, "from_env_vars");
    assert_eq!(config.api_token, "from_cli_args");
}

fn parse_args() -> CliArgs {
    CliArgs {
        url: None,
        user: None,
        api_token: Some("from_cli_args".to_owned()),
    }
}

fn parse_env() -> EnvVars {
    EnvVars {
        url: None,
        user: Some("from_env_vars".to_owned()),
        api_token: None,
    }
}

fn read_conf_file() -> ConfFile {
    ConfFile {
        url: None,
        user: Some("from_conf_file".to_owned()),
        api_token: Some("from_conf_file".to_owned()),
    }
}

如您所注意到的,特质的实现相当重复。未来版本中将有一个过程宏来自动推导它。

许可证

根据您的选择,在以下两种许可证下许可:[Apache License, Version 2.0](https://github.com/a1akris/overwrite/blob/7d6f243d1e76c92ac20af30a614bed891552ba57/LICENSE-APACHE) 或 [MIT license](https://github.com/a1akris/overwrite/blob/7d6f243d1e76c92ac20af30a614bed891552ba57/LICENSE-MIT)。

除非您明确声明,否则您提交的任何贡献,根据 Apache-2.0 许可证定义,将根据上述许可证双重许可,不附加任何额外条款或条件。

无运行时依赖

功能