2个版本
0.1.1 | 2021年2月21日 |
---|---|
0.1.0 | 2020年12月19日 |
#606 in 异步
105KB
2K SLoC
喵
什么是
为Rust提供的异步感知和可扩展的分层配置系统 喵
允许您从多个来源收集配置,包括但不限于
- 文件
- 环境
- 内存中
它围绕 Serde
构建,负责将数据格式转换为其他格式。它经过实战检验且性能良好。 喵
充分利用其功能! 喵
的数据模型允许根据需要分层配置树,并将其转换为Rust结构或直接从树中检索配置值。此外,它允许使用简单的DSL进行配置部分的范围,同时保持相同的功能。它是考虑异步和可扩展性构建的。得益于 async_trait
crate,可以定义异步配置源。
如何
以下是库的基本构建块的流程图。
来源
是例如文件或来自远程服务的数据。它们有两种类型 - 同步(阻塞,不需要 Futures
执行器)和 异步(非阻塞,但需要 Futures
执行器)。
每个来源都与一个 Format
(例如 json
或 yaml
)相关联,由 serde
支持的反序列化器表示。
它们共同构成一个 Provider
或 AsyncProvider
,负责从内部库结构中获取和反序列化配置。一些 Provider
不是由 Source
和 Format
组成的,而是独立的结构,用于从不适合 Source
和 Format
区分的来源获取数据,例如负责获取环境变量的提供者。
所有上述实体都是库公开的 特性。对于您作为 Miau
的用户来说,这意味着如果您发现某些功能缺失(无论是格式还是特定来源),您都可以轻松将其插入到管道中,充分利用其他组件。
提供者都是懒加载的,这意味着除非被告知,否则它们不会执行任何操作。这是由 ConfigurationBuilder
和 AsyncConfigurationBuilder
的责任来调用它们 拥有 的提供者,并适当地分层结果实体以形成 Configuration
。
Configuration
由有序的树(可以说它是一个有序的森林)组成,每个源一个,按顺序分层,以便为您的应用程序的不同环境提供正确的覆盖行为。
在这个阶段,您可以使用结果实体用简单的 DSL 读取配置。
"key1:[index1]:key2:key3:[index2]"
每次您想指定要读取 map 中的条目时,请使用简单的字符串。当您想读取 数组 中的特定索引时,请使用 [number](一个由方括号包围的整数)。不同的键由 ":" 字符分隔。
需要注意的是,由于使用的内存模型,从 Configuration
获取的值不一定总能借用。因此,无法获取所有类型值的 &str
。虽然其中一些可能可行,但出于易于使用的考虑,最好始终检索 String
。同样也适用于所有其他引用。
Configuration
可以转换为任何实现 serde
的 Deserialize
特性的结构体,并且没有借用字段(实际上是实现 DeserializeOwned
)。
库还提供了缩放能力,即允许您关注配置的所选子部分,并将其视为顶级节点。
下面是基本示例。
请记住,由于库中存在多个包含配置的结构体,因此通过所有这些结构体共同实现的通用特性行使读取权限 - ConfigurationRead
。它必须在作用域内才能访问读取方法。
use miau::{
builder::ConfigurationBuilder, configuration::ConfigurationRead, format, format::Json5,
provider::EnvironmentProvider, source::FileSource,
};
use std::collections::HashMap;
use std::env;
fn main() {
let mut some_collection: HashMap<String, String> = HashMap::new();
some_collection.insert("key".into(), "value".into());
let mut builder = ConfigurationBuilder::default();
let result = builder
.add_provider(EnvironmentProvider::with_prefix("ASDFA"))
.add(
FileSource::from_path("./files/config.json"),
format::json(),
)
.add(
FileSource::from_path("./files/config.json5"),
Json5::default(),
)
.add_provider(some_collection)
.build();
let configuration = match result {
Ok(configuration) => configuration,
Err(e) => panic!(
"You should handle it more gracefull in your app! {}",
e.pretty_display()
),
};
// `get` method is defined in ConfigurationRead trait. It has to be in scope!
let from_map_then_array: Option<i32> = configuration.get("map:[1]");
}
有关更多示例,请参阅源代码存储库中的示例文件夹,以了解如何构建配置和定义您自己的来源。
为什么
在用 Rust 编写自己的应用程序时,此库的作者注意到现有的用于创建分层配置的库要么维护不力,要么缺乏对 async
的支持,或者在其他方面扩展性不足。
此库的目标是提供不太可能经常更改的分层配置的核心功能,并通过特性进行扩展。它不打算让 Miau
变得笨重或因特定用例而充满可选依赖项。
这就是为什么它的唯一重依赖项是 serde
,并且它只定义了可以使用标准库实现的 Sources
和 Providers
。只有最流行的格式是 Miau
的一部分,而且它们都带有功能标志。这也是为什么没有实现 async
特性 - 有多个重量级执行器。出于同样的原因,没有包含 HTTP 源 - HTTP 库数量众多。
应单独在 crate 中实现上述实用程序的支持(这是通过公共特性实现的)。
功能标志
默认情况下没有启用任何功能标志。
ini
- 启用对 Ini 格式的支持json
- 启用对 Json 格式的支持msgpack
- 启用对 Message Pack 格式的支持serde_json5
- 启用对 Json5 格式的支持serde_toml
- 启用对 Toml 格式的支持yaml
- 启用对 Yaml 格式的支持all
- 启用所有其他功能标志
贡献
Miau
如果贡献高质量、单元测试并通过其哲学(在 Why
和 How
部分)相匹配,将接受一次性贡献。也欢迎愿意维护此库的人,因为此库的作者认为一个人无法真正长期维护开源库。
Miau
的第一版本中没有包含但可能因某些原因有用的功能:
- 在发生某些事件或定期的情况下刷新配置的机制(然而,最好以通用方式在 crate 外部实现它)
在您的贡献中,请记得根据需要更新文档和资源(使用 generate_assets.sh 脚本)。
许可证
依赖项
~1–2.7MB
~55K SLoC