16 stable releases
3.4.0 | Dec 11, 2023 |
---|---|
3.3.0 | Feb 24, 2023 |
3.1.1 | Dec 18, 2022 |
3.1.0 | Oct 8, 2022 |
1.0.2 | Dec 31, 2021 |
#49 in Configuration
1,563 downloads per month
Used in svd2rust
100KB
2K
SLoC
irx-config library
The irx-config
library provides convenient way to represent/parse configuration from different sources. The main
goals is to be very easy to use and to be extendable.
Features
- Fully compatible with serde
- Full deep merge of nested dictionaries/mappings
- Case sensitive/insensitive parameters names matching/merging
- Sealing secrets during display/debugging
- Get all configuration parameters or just cherry pick few
- Several embedded parsers available via library features:
- Command-line argument (via clap)
- Environment variables
- File based parsers:
JSON
,JSON5
,YAML
andTOML
- Could be extended with custom parsers
Examples
JSON with environment variables
To enable parsers used in example below, one has to add the following to Cargo.toml
:
[dependencies]
irx-config = { version = "3.4", features = ["env", "json"] }
use irx_config::parsers::{env, json};
use irx_config::ConfigBuilder;
use serde::Deserialize;
#[derive(Deserialize)]
struct Conf {
id: u32,
logger: String,
tag: String,
}
// Data from two parsers will be merged. The values from parser appended first (`JSON`)
// will take precedence if values have a same names
let config = ConfigBuilder::default()
.append_parser(
json::ParserBuilder::default()
.default_path("config.json")
.build()?,
)
.append_parser(
env::ParserBuilder::default()
.default_prefix("APP_")
.build()?,
)
.load()?;
let conf_data: Conf = config.get()?;
Command-line, TOML and environment variables
To enable parsers used in example below, one has to add the following to Cargo.toml
:
[dependencies]
irx-config = { version = "3.4", features = ["cmd", "env", "toml-parser"] }
use clap::app_from_crate;
use irx_config::parsers::{cmd, env, toml};
use irx_config::ConfigBuilder;
use serde::Deserialize;
fn localhost() -> String {
"localhost".into()
}
#[derive(Deserialize)]
struct Logger {
level: String,
path: String,
}
#[derive(Deserialize)]
struct Connection {
#[serde(default = "localhost")]
host: String,
port: u16,
}
#[derive(Deserialize)]
struct Conf {
id: u32,
logger: Logger,
connection: Connection,
}
let app = app_from_crate!();
// Data from three parsers will be merged. The values from parser appended first (`cmd`)
// will take precedence if values have a same names
let config = ConfigBuilder::default()
.append_parser(
cmd::ParserBuilder::new(app)
.exit_on_error(true)
.build()?,
)
.append_parser(
toml::ParserBuilder::default()
.default_path("config.toml")
.path_option("config")
.build()?,
)
.append_parser(
env::ParserBuilder::default()
.default_prefix("APP_")
.prefix_option("prefix")
.build()?,
)
.load()?;
let conf_data: Conf = config.get()?;
Custom parser
use irx_config::{AnyResult, Case, ConfigBuilder, Parse, Value};
use serde::Deserialize;
use std::borrow::Cow;
#[derive(Deserialize)]
struct Conf {
id: u32,
logger: String,
tag: String,
}
struct JsonStringParser<'a> {
data: Cow<'a, str>,
}
impl<'a> JsonStringParser<'a> {
pub fn new(data: impl Into<Cow<'a, str>>) -> Self {
JsonStringParser { data: data.into() }
}
}
impl Case for JsonStringParser<'_> {}
impl Parse for JsonStringParser<'_> {
fn parse(&mut self, _value: &Value) -> AnyResult<Value> {
Ok(serde_json::from_str(&self.data)?)
}
}
let data = r#"{ "id": 42, "logger": "file", "tag": "test" }"#;
let config = ConfigBuilder::load_one(JsonStringParser::new(data))?;
let conf_data: Conf = config.get()?;
JSON parser get partial data
To enable parsers used in example below, one has to add the following to Cargo.toml
:
[dependencies]
irx-config = { version = "3.4", features = ["json"] }
use irx_config::parsers::json;
use irx_config::ConfigBuilder;
use serde::Deserialize;
fn localhost() -> String {
"localhost".into()
}
#[derive(Deserialize)]
struct Logger {
level: String,
path: String,
}
#[derive(Deserialize)]
struct Connection {
#[serde(default = "localhost")]
host: String,
port: u16,
}
let config = ConfigBuilder::load_one(
json::ParserBuilder::default()
.default_path("config.json")
.build()?,
)?;
let logger: Logger = config.get_by_key_path("logger")?.unwrap();
let port: u16 = config.get_by_key_path("connection:port")?.unwrap();
Dependencies
~2.1–4MB
~94K SLoC