config_rw 2.1.0

配置文件读取与写入
Documentation
# 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 项目中使用,特别是需要跨动态库访问配置的场景。