Build

Overwrite

A simple trait that defines how to overwrite a type by another types. Mainly useful to create an app configuration from different sources.

Example

```rust use overwrite::Overwrite;

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

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

struct CliArgs { url: Option, user: Option, api_token: Option }

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

struct ConfFile { url: Option, user: Option, api_token: Option, }

impl Overwrite for Config { fn overwritemut(&mut self, conffile: ConfFile) -> &mut Self { self.url.overwritemut(conffile.url); self.user.overwritemut(conffile.user); self.apitoken.overwritemut(conffile.apitoken); self } }

struct EnvVars { url: Option, user: Option, api_token: Option, }

impl Overwrite for Config { fn overwritemut(&mut self, envvars: EnvVars) -> &mut Self { self.url.overwritemut(envvars.url); self.user.overwritemut(envvars.user); self.apitoken.overwritemut(envvars.apitoken); self } }

fn main() { let cliargs = parseargs(); let conffile = readconffile(); let envvars = 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 parseargs() -> CliArgs { CliArgs { url: None, user: None, apitoken: Some("fromcliargs".to_owned()), } }

fn parseenv() -> EnvVars { EnvVars { url: None, user: Some("fromenvvars".toowned()), api_token: None, } }

fn readconffile() -> ConfFile { ConfFile { url: None, user: Some("fromconffile".toowned()), apitoken: Some("fromconffile".to_owned()), } } ```

As you have noticed the trait implementation is quite repetetive. There will be a proc macro to automatically derive it in the future versions.

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.