4个版本

0.2.1 2024年5月4日
0.2.0 2024年5月1日
0.1.1 2024年4月27日
0.1.0 2024年4月27日

配置分类中排名第153

MIT许可

42KB
128

Confgr

一个轻量级的Rust应用程序配置推导宏。


由Ki用❤️构建

概述

Config推导宏通过以下顺序自动从源加载设置,从而简化应用程序的配置:

  1. 环境变量.
  2. 配置文件(例如,tomljsonyamlinironjson5)。
  3. 默认值.

主要功能

  • 简单性:最小化样板代码。定义您的配置结构体,自定义宏,然后就可以使用了。
  • 灵活性:支持多种配置文件格式,包括tomljsonyamlinironjson5
  • 集成:与其他Crates(如smart_default)协同工作。

还有一些有用的辅助属性,可以自定义推导宏的行为。

属性 功能
prefix 为环境变量设置前缀。可以在结构体或字段级别应用。
path 指定配置文件的静态路径。文件扩展名可以省略(尽管通常不应省略)。
env_path 在运行时解析环境变量,以确定配置文件路径。
default_path 指定当env_path确定的路径不存在时使用的回退路径。
key 覆盖默认环境变量名称。这将忽略前缀并直接使用提供的键。
name 转发到#[serde(rename = "_")]以在序列化/反序列化期间重命名字段。它不会影响环境变量名称。
nest 对于必须继承 Config(用于嵌套配置结构体)的非标准类型,此属性是必需的。
跳过 跳过从环境变量加载属性。对于在配置文件中存在但未实现 FromStr 的类型,此属性是必需的。
分隔符 指定一个字符来分隔前缀和字段名。默认分隔符是 "_"。

路径属性行为

  • env_path:将提供的环境变量解析为配置文件路径。此选项优于 pathdefault_path,但如果文件或环境不存在,则不会引发 panic。
  • path:直接设置配置文件的路径。当设置时,default_path 不可用。如果文件不存在,将引发 panic。
  • default_path:与 path 相同,但如果文件不存在,则不会引发 panic。

使用方法

serde 是必需的依赖项。

 [dependencies]
 confgr = "0.2.0"
 serde = { version = "1.0", features = ["derive"] }

然后按照以下方式定义配置

use confgr::prelude::*;

#[derive(Config)]
#[config(path = "docs.toml", prefix = "APP")]
pub struct AppConfig {
  port: u32,
  address: String,
  #[config(key = "DEBUG_MODE")]
  debug: bool,
}

// Default implementation is required.
impl Default for AppConfig {
  fn default() -> Self {
    Self {
      port: 3000,
      address: "127.0.0.1".to_string(),
      debug: false
    }
  }
}

std::env::set_var("APP_PORT", "4000");
std::env::set_var("DEBUG_MODE", "true");

let settings = AppConfig::load_config();

assert_eq!(settings.port, 4000);
assert_eq!(settings.address, "127.0.0.1");
assert!(settings.debug)

有关更多示例,请查看 examples 目录。

警告/陷阱

  • 嵌套结构体不会根据其自身的 path 属性加载单独的文件。如果需要加载多个文件,必须使用多个结构体并多次调用 load_config()。这可能在未来的版本中发生变化。
  • 未实现 FromStr 的类型必须使用 #[config(skip)]#[config(nest)]
  • separator 字符仅插入到前缀和字段名之间,不会插入到解析的字段名的任何部分。
  • prefix 按字段或整个结构体应用,但如果使用了 #[config(key = "_")],则会被忽略。
  • 所有配置结构体都必须实现 Default
  • 用于配置结构体字段的自定义类型必须实现 DeserializeCloneDebug
  • Option 目前与实现 Confgr 的类型上的 #[config(nest)] 不兼容。

调试

在使用宏时遇到问题时,以下方法可能有用。

验证环境变量

可以使用 get_env_keys() 方法检索由 derive 宏构建的环境变量键名。

use std::collections::HashMap;
use confgr::prelude::*;

#[derive(Config, Default)]
#[config(prefix = "APP")]
pub struct AppConfig {
    port: u32,
    #[config(separator = "__")]
    address: String,
    #[config(key = "DEBUG_MODE")]
    debug: bool,
}

let keys: HashMap<String, String> = AppConfig::get_env_keys();

assert_eq!(keys["port"], "APP_PORT");
assert_eq!(keys["address"], "APP__ADDRESS");
assert_eq!(keys["debug"], "DEBUG_MODE");

验证配置文件路径

您可以使用 check_file() 确保配置文件可以通过提供的 pathpath_envdefault_path 属性访问。

use confgr::prelude::*;

#[derive(Config, Default)]
#[config(path = "docs.toml", env_path = "APP_CONFIG_FILE")]
pub struct AppConfig {
    port: u32,
    debug: bool,
}

std::env::set_var("APP_CONFIG_FILE", "env_config.toml");
AppConfig::check_file().expect("Failed to open configuration file.");

std::env::remove_var("APP_CONFIG_FILE");
AppConfig::check_file().expect("Failed to open configuration file.");

测试反序列化

可以使用 deserialize_from_file() 方法手动测试配置的反序列化步骤。返回一个 Result<Self::Layer, ConfgrError>

use confgr::prelude::\*;

#[derive(Config, Default)] #[config(path = "docs.toml")]
pub struct AppConfig {
port: u32,
debug: bool,
}

let config = AppConfig::deserialize_from_file().expect("Failed to deserialize configuration.");
println!("Deserialized configuration: {:?}", config);

注意事项

  • 版本不稳定:截至目前,此crate处于不稳定开发阶段,我保留在将来版本中进行破坏性更改的权利,而无需承担向后兼容的义务。
  • 生产使用注意事项:这是我的第一个公开的Rust crate,虽然它完全功能齐全并且对我很有用,但在关键的生产环境中,在没有彻底测试的情况下,不建议过度依赖此库,尤其是在需要稳定性和性能保证的情况下。
  • 贡献:欢迎贡献!无论是功能请求、错误报告还是拉取请求,我都希望得到一些建设性的反馈!

我强烈推荐查看 config crate,因为它是一个功能完整的非proc-macro替代方案。实际上,此crate依赖于 config 进行文件解析。

依赖关系

~2–3MB
~62K SLoC