7 个不稳定版本 (3 个破坏性更新)
0.3.0 | 2024年6月21日 |
---|---|
0.2.0 | 2024年1月16日 |
0.1.3 | 2023年10月17日 |
0.0.1 | 2023年10月2日 |
#123 in 配置
105KB
2K SLoC
插件配置管理器(进行中)
特性
- 加载、解析、合并和验证配置。
- 从 URL 加载配置。
- 内置文件系统、环境变量和 HTTP 配置加载器(Cargo 功能)。
- 内置环境变量、JSON、YAML 和 TOML 配置解析器(Cargo 功能)。
- 易于实现自己的配置加载器或解析器。
- 能够跳过不同配置加载器的软错误(例如,如果配置文件不存在)。
- 易于阅读的错误信息。
- 易于重新加载配置。
- log 和 tracing 集成。
架构
Example URLs:
file:///etc/directory/
file://file.[json|yml|toml|env]
http://config-server.tld/path/to/config
env://?prefix=APP_NAME
custom://custom?custom=custom
┌──────────────────────────────────────────────┐ ┌──────────────────────┐ ┌───┐ ┌─────────┐
│ FILE SYSTEM │ │ │ │ │ │ │
│ ┌───────────────┐ ┌────────────────────────┐ │ │ │ │ │ │ │
│ │/etc/directory/│ │file.[json|yml|toml|env]│ │ │REST API (e.g. Consul)│ │Env│ │ Custom │
│ └────────────┬──┘ └──┬─────────────────────┘ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ │
└──────────────┼───────┼───────────────────────┘ └─┬────────────────────┘ └─┬─┘ └──┬──────┘
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
┌──────────────┼───────┼───────────────────────────┼────────────────────────┼──────┼──────┐
│ plugx-config │ │ │ │ │ │
│ ┌────────────┼───────┼───────────────────────────┼────────────────────────┼──────┼────┐ │
│ │ Loader │ │ │ │ │ │ │
│ │ ┌──────────▼───────▼───┐ ┌─────────────────────▼─┐ ┌────────────────────▼┐ ┌───▼──┐ │ │
│ │ │ LoaderFs │ │ LoaderHttp │ │ LoaderEnv │ │Custom│ │ │
│ │ └──────────┬───────┬──┬┘ └─────────────────────┬─┘ └────────────┬────────┘ └───┬──┘ │ │
│ │ │ │ │ │ │ │ │ │
│ └────────────┼───────┼──┼────────────────────────┼────────────────┼──────────────┼────┘ │
│ │ │ │ │ │ │ │
│ │ │ └───────────────┐ │ │ │ │
│ │ │ │ │ │ │ │
│ ┌────────────┼───────┼──────────────────┼────────┼────────────────┼──────────────┼────┐ │
│ │ Parser │ │ │ │ │ │ │ │
│ │ ┌──────────▼───┐ ┌─▼──────────────┐ ┌─▼────────▼─────┐ ┌────────▼────────┐ ┌───▼──┐ │ │
│ │ │ ParserYaml │ │ ParserToml │ │ ParserJson │ │ ParserEnv │ │Custom│ │ │
│ │ └──────────┬───┘ └─┬──────────────┘ └─┬────────┬─────┘ └────────┬────────┘ └───┬──┘ │ │
│ │ │ │ │ │ │ │ │ │
│ └────────────┼───────┼──────────────────┼────────┼────────────────┼──────────────┼────┘ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ ┌────────────▼───────▼──────────────────▼────────▼────────────────▼──────────────▼────┐ │
│ │ Merge │ │
│ └─────────────────────────────────────────┬───────────────────────────────────────────┘ │
│ │ │
│ │ │
│ ┌─────────────────────────────────────────▼───────────────────────────────────────────┐ │
│ │ Validate │ │
│ └─────────────────────────────────────────┬───────────────────────────────────────────┘ │
│ │ │
└───────────────────────────────────────────┼─────────────────────────────────────────────┘
│
│
▼
Vec<(Name, Config)>
基本用法
在这个示例中,我们将从目录和环境变量加载我们的插件配置。
这里我们有四个配置文件,分别对应四个插件 foo
、bar
、baz
和 qux
,它们位于我们的示例 tests/etc
目录中
$ tree tests/etc
tests/etc
├── bar.json
├── baz.toml
├── foo.env
└── qux.yml
tests/etc/bar.json
{
"sqlite": {
"recreate": true
}
}
tests/etc/baz.toml
[logging]
format = "json"
tests/etc/foo.env
SERVER__PORT="8080" # listen port
tests/etc/qux.yml
https:
follow_redirects: false
此外,我们还设置了以下环境变量
export APP_NAME__FOO__SERVER__ADDRESS="127.0.0.1"
export APP_NAME__BAR__SQLITE__FILE="/path/to/app.db"
export APP_NAME__BAZ__LOGGING__LEVEL="debug"
export APP_NAME__QUX__HTTPS__INSECURE="false"
示例 main.rs
use plugx_config::{
ext::anyhow::{Context, Result},
Configuration, Url,
};
fn main() -> Result<()> {
let url_list: Vec<Url> = get_url_list_from_cmd_args()?;
let mut configuration = Configuration::new();
url_list
.into_iter()
.try_for_each(|url| configuration.add_url(url))?;
// Load & Parse & Merge & print:
configuration
.load_parse_merge(true)?
.iter()
.for_each(|(plugin_name, configuration)| println!("{plugin_name}: {configuration}"));
Ok(())
}
fn get_url_list_from_cmd_args() -> Result<Vec<Url>> {
std::env::args()
.skip(1)
.try_fold(Vec::new(), |mut list, arg| {
list.push(
Url::parse(&arg).with_context(|| format!("Could not parse URL `{arg}`"))?,
);
Ok(list)
})
}
输出
$ /path/to/main 'env://?prefix=APP_NAME' 'fs:///tests/etc/?strip-slash=true'
bar: {"sqlite": {"recreate": true, "file": "/path/to/app.db"}}
foo: {"server": {"address": "127.0.0.1", "port": 8080}}
baz: {"logging": {"level": "debug", "format": "json"}}
qux: {"https": {"follow_redirects": false, "insecure": false}}
依赖
~4–7MB
~153K SLoC