1 unstable release
0.0.1 | Jan 24, 2024 |
---|
#29 in #cli-config
120KB
3.5K
SLoC
⚙️ Config
Once someone said
Config Solutions Absolutly Suck
This crate tries to solve this problem and make it suck less.
It comes with built-in support for parsing cli arguments, environment variables and files without requiring you to write more than just the definition of your configuration structs. Another goal of this crate is to be extensible and allow you to write your own sources. You could, for example, implement config sources like databases or remote services. See Advanced Usage for more information.
🚀 How to use it
Since this crate is built on top of serde, please add serde as a dependency to your Cargo.toml
.
cargo add serde --features derive
After that, you can use the #[derive(Config)]
macro call to derive the Config
trait for your configuration struct.
All structs implementing Config
are also required to implement serde::Deserialize
.
#[derive(config::Config, serde::Deserialize)]
struct MyConfig {
// ...
}
Now you can use the ConfigBuilder
to parse your configuration from various sources and merge them together into your configuration struct.
use config::sources;
#[derive(config::Config, serde::Deserialize)]
struct MyConfig {
// ...
}
fn main() -> Result<(), config::ConfigError> {
let mut builder = config::ConfigBuilder::new();
// From CLI arguments
builder.add_source(sources::CliSource::new()?);
// From environment variables
builder.add_source(sources::EnvSource::with_prefix("TEST")?);
// From config file
builder.add_source(sources::FileSource::with_path("config.toml")?);
// Build the final configuration
let config: MyConfig = builder.build()?;
// ...
Ok(())
}
- The first line creates a new
ConfigBuilder
. - The next line adds the
CliSource
to the builder which parses cli arguments using theclap
crate. You can call your executable with--help
to see the generated help message. - The third line adds the
EnvSource
to the builder which parses environment variables with the given prefix. - The third source, called
FileSource
, is added to parse the configuration from a file with the given path. The file format will be detected automatically during runtime. It can be TOML, YAML or JSON. - Finally, you can call
build
to build the final configuration. This will parse all sources and merge them together into your configuration struct. The ealier a source is added, the higher its priority is. This means that values from sources added later will not overwrite values from sources added earlier.
Example
See the examples folder for examples.
🔧 Advanced usage
How to define your own config source
To define your own config source, you need to implement the Source
trait.
This requires you to implement the get_key
method which returns a Value
for a given KeyPath
.
That's it. It's as simple as that. Now you can add your source to a ConfigBuilder
and use it to parse your configuration.
🔬 How it works under the hood
As soon as your type implements the Config
trait, it supports getting its keys as a KeyGraph
. This is a graph of all keys in that type. It is used by the ConfigBuilder
to retrieve the values from the added sources by iterating all keys.
Please see the docs for Config
, ConfigBuilder
, Source
and KeyGraph
for more information.
Dependencies
~5–6.5MB
~122K SLoC