# TOML 配置管理器使用说明
这是一个基于 `toml_edit` 库实现的配置管理器,支持跨动态库访问、保留注释、动态修改配置等功能。
## 特性
- ✅ **保留注释**:修改配置时保持原有注释和格式
- ✅ **跨动态库访问**:使用静态全局变量,支持在不同模块间共享配置
- ✅ **点表示法**:支持 `a.b.c` 格式访问嵌套配置
- ✅ **类型安全**:提供类型化的读取和设置函数
- ✅ **动态修改**:运行时修改配置并保存到文件
- ✅ **成熟可靠**:基于 `toml_edit` 和 `serde_json` 等成熟库
## 依赖
```toml
[dependencies]
toml_edit = "0.22"
parking_lot = "0.12"
serde_json = "1"
once_cell = "1"
```
## 基本用法
### 1. 初始化配置
```rust
use tick_rhino::config::init_config;
// 初始化配置管理器,加载配置文件
init_config("config.toml")?;
```
### 2. 读取配置
```rust
use tick_rhino::config::{get_arg, get_string, get_i64, get_f64, get_bool};
use serde_json::Value;
// 使用 get_arg 获取原始 JSON 值
let host: Value = get_arg("database.host");
// 使用类型化函数获取特定类型
let port = get_i64("database.port").unwrap_or(3306);
let timeout = get_f64("database.timeout").unwrap_or(10.0);
let debug_enabled = get_bool("app.debug").unwrap_or(false);
let app_name = get_string("app.name").unwrap_or("unknown".to_string());
// 读取嵌套配置
let cache_enabled = get_bool("app.features.cache_enabled").unwrap_or(false);
```
### 3. 修改配置
```rust
use tick_rhino::config::{set_arg, set_string, set_i64, set_f64, set_bool};
use serde_json::Value;
// 使用类型化函数设置配置
set_string("database.host", "127.0.0.1".to_string())?;
set_i64("database.port", 3306)?;
set_bool("app.debug", true)?;
set_f64("trading.stop_loss_percent", 0.03)?;
// 使用 set_arg 设置复杂数据类型
let array_value = Value::Array(vec![
Value::String("item1".to_string()),
Value::String("item2".to_string()),
Value::Number(serde_json::Number::from(42)),
]);
set_arg("complex.array", array_value)?;
```
### 4. 保存配置
```rust
use tick_rhino::config::save_config;
// 保存配置到文件,保留注释和格式
save_config()?;
```
## 配置文件示例
```toml
# 这是一个示例配置文件
# 支持注释,修改配置时注释会被保留
# 数据库配置
[database]
host = "localhost"
port = 5432
enabled = true
# 数据库连接超时时间(秒)
timeout = 30.0
# 应用配置
[app]
name = "tick_rhino"
version = "1.0.0"
debug = false
# 应用特性配置
[app.features]
logging = true
metrics = false
cache_enabled = true
# 交易配置
[trading]
max_position_size = 1000000
stop_loss_percent = 0.05
take_profit_percent = 0.10
```
## 完整示例
```rust
use tick_rhino::config::{
init_config, get_arg, set_arg, save_config,
get_string, get_i64, get_f64, get_bool,
set_string, set_i64, set_f64, set_bool
};
use serde_json::Value;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 初始化配置管理器
init_config("config.toml")?;
// 读取配置
let host: Value = get_arg("database.host");
let port = get_i64("database.port").unwrap_or(3306);
let debug_enabled = get_bool("app.debug").unwrap_or(false);
println!("数据库主机: {}", host);
println!("数据库端口: {}", port);
println!("调试模式: {}", debug_enabled);
// 修改配置
set_string("database.host", "127.0.0.1".to_string())?;
set_i64("database.port", 3306)?;
set_bool("app.debug", true)?;
// 添加新配置
set_string("new_section.new_key", "new_value".to_string())?;
// 保存配置
save_config()?;
println!("配置已保存,注释和格式得到保留");
Ok(())
}
```
## 跨模块使用
由于使用了全局静态变量,配置管理器可以在任何模块中使用,无需传递配置对象:
```rust
// 在模块 A 中
use tick_rhino::config::{get_i64, set_i64};
pub fn module_a_function() -> Result<(), Box<dyn std::error::Error>> {
let port = get_i64("network.server_port").unwrap_or(8080);
println!("模块 A 读取端口: {}", port);
set_i64("network.server_port", 9090)?;
println!("模块 A 修改端口为: 9090");
Ok(())
}
// 在模块 B 中
use tick_rhino::config::{get_i64, get_string};
pub fn module_b_function() {
let port = get_i64("network.server_port").unwrap_or(8080);
let level = get_string("logging.level").unwrap_or("info".to_string());
println!("模块 B 读取端口: {}", port); // 输出: 9090
println!("模块 B 读取日志级别: {}", level);
}
```
## 动态库使用
该配置管理器特别适合在动态库中使用:
```rust
#[no_mangle]
pub extern "C" fn dll_init() -> i32 {
match init_config("config.toml") {
Ok(_) => {
println!("配置管理器初始化成功");
0
}
Err(e) => {
eprintln!("配置管理器初始化失败: {}", e);
-1
}
}
}
#[no_mangle]
pub extern "C" fn dll_get_config(key: *const i8) -> i32 {
// 在 C 函数中使用配置管理器
let port = get_i64("network.server_port").unwrap_or(8080);
port as i32
}
```
## API 参考
### 初始化函数
- `init_config(path)` - 初始化配置管理器并加载配置文件
### 读取函数
- `get_arg(path)` - 获取原始 JSON 值
- `get_string(path)` - 获取字符串值
- `get_i64(path)` - 获取 64 位整数值
- `get_f64(path)` - 获取 64 位浮点数值
- `get_bool(path)` - 获取布尔值
### 设置函数
- `set_arg(path, value)` - 设置 JSON 值
- `set_string(path, value)` - 设置字符串值
- `set_i64(path, value)` - 设置 64 位整数值
- `set_f64(path, value)` - 设置 64 位浮点数值
- `set_bool(path, value)` - 设置布尔值
### 保存函数
- `save_config()` - 保存配置到文件
## 注意事项
1. **初始化顺序**:必须先调用 `init_config()` 初始化配置管理器
2. **线程安全**:所有函数都是线程安全的,使用 `parking_lot::RwLock` 保护
3. **错误处理**:读取不存在的配置会返回 `Value::Null` 或 `None`
4. **文件权限**:确保对配置文件有读写权限
5. **注释保留**:只有通过 `toml_edit` 修改的配置才能保留注释
## 运行示例
```bash
# 运行配置管理器测试
cargo test config
# 运行演示测试
cargo test config_demo
```
这个配置管理器提供了完整的 TOML 配置管理功能,适合在 Rust 项目中使用,特别是需要跨动态库访问配置的场景。