#config-parser #arguments-parser #secret #json-parser #configuration #environment #command-line

irx-config

该库提供了一种方便的方法来表示/解析来自不同来源的配置

16个稳定版本

3.4.0 2023年12月11日
3.3.0 2023年2月24日
3.1.1 2022年12月18日
3.1.0 2022年10月8日
1.0.2 2021年12月31日

#34配置

Download history 744/week @ 2024-04-08 493/week @ 2024-04-15 379/week @ 2024-04-22 394/week @ 2024-04-29 407/week @ 2024-05-06 380/week @ 2024-05-13 273/week @ 2024-05-20 319/week @ 2024-05-27 253/week @ 2024-06-03 393/week @ 2024-06-10 411/week @ 2024-06-17 347/week @ 2024-06-24 333/week @ 2024-07-01 217/week @ 2024-07-08 216/week @ 2024-07-15 250/week @ 2024-07-22

1,040 每月下载量
svd2rust 中使用

BSD-2-Clause

100KB
2K SLoC

irx-config库

GitHub top language Crates.io Crates.io Crates.io Libraries.io dependency status for latest release docs.rs

irx-config 库提供了一种方便的方法来表示/解析来自不同来源的配置。主要目标是使用简单且易于扩展。

功能

  • 完全兼容 serde
  • 嵌套字典/映射的全深度合并
  • 大小写敏感/不敏感的参数名称匹配/合并
  • 在显示/调试期间密封机密信息
  • 获取所有配置参数或仅选择部分参数
  • 通过库功能提供几个嵌入的解析器
    • 命令行参数(通过 clap
    • 环境变量
    • 基于文件的解析器:JSONJSON5YAMLTOML
  • 可以扩展自定义解析器

示例

带有环境变量的JSON

为了启用下面示例中使用的解析器,必须在 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()?;

命令行、TOML和环境变量

为了启用下面示例中使用的解析器,必须在 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()?;

自定义解析器

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解析器获取部分数据

为了启用下面示例中使用的解析器,必须在 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();

依赖关系

~2–4MB
~91K SLoC