Skip to main content

wae_config/
lib.rs

1//! WAE Config - 配置管理模块
2//!
3//! 提供统一的配置加载和管理能力,基于 figment 库实现。
4//! 支持多层级配置合并:环境变量 > 配置文件 > 默认值。
5
6#![warn(missing_docs)]
7
8use figment::{
9    Figment,
10    providers::{Env, Format, Toml, Yaml},
11};
12use serde::de::DeserializeOwned;
13use wae_types::{WaeError, WaeResult};
14
15/// 配置加载器
16///
17/// 支持从多种来源加载配置,并按优先级合并。
18/// 优先级从高到低:环境变量 > 指定配置文件 > 默认配置文件 > 默认值
19pub struct ConfigLoader {
20    figment: Figment,
21}
22
23impl Default for ConfigLoader {
24    fn default() -> Self {
25        Self::new()
26    }
27}
28
29impl ConfigLoader {
30    /// 创建新的配置加载器
31    pub fn new() -> Self {
32        Self { figment: Figment::new() }
33    }
34
35    /// 从 TOML 文件加载配置
36    ///
37    /// # Arguments
38    /// * `path` - 配置文件路径
39    pub fn with_toml(mut self, path: &str) -> Self {
40        self.figment = self.figment.merge(Toml::file(path));
41        self
42    }
43
44    /// 从 YAML 文件加载配置
45    ///
46    /// # Arguments
47    /// * `path` - 配置文件路径
48    pub fn with_yaml(mut self, path: &str) -> Self {
49        self.figment = self.figment.merge(Yaml::file(path));
50        self
51    }
52
53    /// 从环境变量加载配置
54    ///
55    /// # Arguments
56    /// * `prefix` - 环境变量前缀,如 "APP_"
57    pub fn with_env(mut self, prefix: &str) -> Self {
58        self.figment = self.figment.merge(Env::prefixed(prefix));
59        self
60    }
61
62    /// 从环境变量加载配置(带分隔符)
63    ///
64    /// # Arguments
65    /// * `prefix` - 环境变量前缀
66    /// * `separator` - 嵌套分隔符,如 "__"
67    pub fn with_env_separator(mut self, prefix: &str, separator: &str) -> Self {
68        self.figment = self.figment.merge(Env::prefixed(prefix).split(separator));
69        self
70    }
71
72    /// 合并默认值
73    ///
74    /// # Arguments
75    /// * `defaults` - 默认配置值
76    pub fn with_defaults<T: serde::Serialize>(mut self, defaults: &T) -> Self {
77        self.figment = self.figment.merge(figment::providers::Serialized::defaults(defaults));
78        self
79    }
80
81    /// 提取配置到指定类型
82    ///
83    /// # Type Parameters
84    /// * `T` - 配置类型,需实现 `DeserializeOwned`
85    pub fn extract<T: DeserializeOwned>(self) -> WaeResult<T> {
86        self.figment.extract().map_err(|e| {
87            let msg = e.to_string();
88            if msg.contains("missing field") { WaeError::config_missing(msg) } else { WaeError::config_invalid("config", msg) }
89        })
90    }
91
92    /// 提取配置到指定类型(带自定义错误消息)
93    ///
94    /// # Type Parameters
95    /// * `T` - 配置类型,需实现 `DeserializeOwned`
96    /// * `context` - 错误上下文信息
97    pub fn extract_with_context<T: DeserializeOwned>(self, context: &str) -> WaeResult<T> {
98        self.extract().map_err(|e| WaeError::internal(format!("{}: {}", context, e)))
99    }
100}
101
102/// 快速加载配置的便捷函数
103///
104/// 从默认位置加载配置文件,并合并环境变量。
105///
106/// # Type Parameters
107/// * `T` - 配置类型
108///
109/// # Arguments
110/// * `config_path` - 配置文件路径
111/// * `env_prefix` - 环境变量前缀
112pub fn load_config<T: DeserializeOwned>(config_path: &str, env_prefix: &str) -> WaeResult<T> {
113    ConfigLoader::new().with_toml(config_path).with_env(env_prefix).extract()
114}
115
116/// 从环境变量加载配置
117///
118/// # Type Parameters
119/// * `T` - 配置类型
120///
121/// # Arguments
122/// * `prefix` - 环境变量前缀
123pub fn from_env<T: DeserializeOwned>(prefix: &str) -> WaeResult<T> {
124    ConfigLoader::new().with_env(prefix).extract()
125}