use config_rw::{get_arg, init_config, save_config, set_arg};
use config_rw::{get_bool, get_f64, get_i64, get_string};
use config_rw::{set_bool, set_f64, set_i64, set_string};
type StdBoxError = Box<dyn std::error::Error + Send + Sync>;
type R<V = ()> = Result<V, StdBoxError>;
use serde_json::Value;
fn main() -> R {
test_config_rw()?;
demo_cross_module_config()?;
demo_complex_config()?;
Ok(())
}
fn test_config_rw() -> R {
init_config("config.toml")?;
let host: Value = get_arg("database.host");
assert_eq!(host.is_string(), true);
let port = get_i64("database.port").unwrap_or(3306);
assert!(port > 0);
let timeout = get_f64("database.timeout").unwrap_or(10.0);
assert!(timeout > 0.0);
let _debug_enabled = get_bool("app.debug").unwrap_or(false);
let app_name = get_string("app.name").unwrap_or("unknown".to_string());
assert_ne!(app_name, "");
let _cache_enabled = get_bool("app.features.cache_enabled").unwrap_or(false);
let max_position = get_i64("trading.max_position_size").unwrap_or(0);
assert!(max_position >= 0);
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_string("new_section.new_key", "new_value".to_string())?;
set_i64("performance.max_threads", 8)?;
let new_host = get_string("database.host").unwrap();
assert_eq!(new_host, "127.0.0.1");
let new_port = get_i64("database.port").unwrap();
assert_eq!(new_port, 3306);
let debug_mode = get_bool("app.debug").unwrap();
assert_eq!(debug_mode, true);
let new_config = get_string("new_section.new_key").unwrap();
assert_eq!(new_config, "new_value");
let max_threads = get_i64("performance.max_threads").unwrap();
assert_eq!(max_threads, 8);
save_config()?;
let saved_host = get_string("database.host").unwrap();
assert_eq!(saved_host, "127.0.0.1");
Ok(())
}
pub fn demo_cross_module_config() -> R {
let server_port = get_i64("network.server_port").unwrap_or(8080);
assert!(server_port > 0);
let log_level = get_string("logging.level").unwrap_or("info".to_string());
assert_ne!(log_level, "");
set_i64("network.server_port", 9090)?;
set_string("logging.level", "debug".to_string())?;
let new_port = get_i64("network.server_port").unwrap();
let new_level = get_string("logging.level").unwrap();
assert_eq!(new_port, 9090);
assert_eq!(new_level, "debug");
Ok(())
}
pub fn demo_cross_module_access() -> R {
module_a()?;
module_b()?;
Ok(())
}
fn module_a() -> R {
set_i64("cross_module.server_port", 8080)?;
let port = get_i64("cross_module.server_port").unwrap();
assert_eq!(port, 8080);
set_i64("cross_module.max_connections", 500)?;
let max_conn = get_i64("cross_module.max_connections").unwrap();
assert_eq!(max_conn, 500);
Ok(())
}
fn module_b() -> R {
let port = get_i64("cross_module.server_port").unwrap();
let max_conn = get_i64("cross_module.max_connections").unwrap();
assert_eq!(port, 8080);
assert_eq!(max_conn, 500);
Ok(())
}
pub fn demo_complex_config() -> R {
set_string("complex_demo.nested.key", "nested_value".to_string())?;
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_demo.test_array", array_value)?;
let mut obj = serde_json::Map::new();
obj.insert("name".to_string(), Value::String("test_object".to_string()));
obj.insert("count".to_string(), Value::Number(serde_json::Number::from(99)));
obj.insert("enabled".to_string(), Value::Bool(true));
set_arg("complex_demo.test_object", Value::Object(obj))?;
let nested_value = get_string("complex_demo.nested.key").unwrap();
assert_eq!(nested_value, "nested_value");
let array_config = get_arg("complex_demo.test_array");
assert_eq!(array_config.is_array(), true);
let Value::Array(arr) = array_config else {
panic!("Expected array configuration");
};
assert_eq!(arr.len(), 3);
assert_eq!(arr[0], Value::String("item1".to_string()));
assert_eq!(arr[1], Value::String("item2".to_string()));
assert_eq!(arr[2], Value::Number(serde_json::Number::from(42)));
let object_config = get_arg("complex_demo.test_object");
assert_eq!(object_config.is_object(), true);
let Value::Object(obj) = object_config else {
panic!("Expected object configuration");
};
assert_eq!(obj.len(), 3);
assert_eq!(obj.get("name").unwrap(), &Value::String("test_object".to_string()));
assert_eq!(obj.get("count").unwrap(), &Value::Number(serde_json::Number::from(99)));
assert_eq!(obj.get("enabled").unwrap(), &Value::Bool(true));
save_config()?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_demo_priority() -> R {
init_config("config.toml")?;
let host = get_string("database.host");
assert!(host.is_some(), "数据库主机配置应该存在");
let port = get_i64("database.port");
assert!(port.is_some(), "数据库端口配置应该存在");
assert!(port.unwrap() > 0, "数据库端口应该大于0");
let debug = get_bool("app.debug");
assert!(debug.is_some(), "调试模式配置应该存在");
let _server_port = get_i64("SERVER_PORT");
let _custom_config = get_string("CUSTOM_CONFIG");
let app_name = get_string("app.name");
assert!(app_name.is_some(), "应用名称配置应该存在");
assert!(!app_name.unwrap().is_empty(), "应用名称不应该为空");
Ok(())
}
#[test]
fn test_demo_auto_save() -> R {
init_config("config.toml")?;
let test_value = "自动保存的值";
let test_number = 12345i64;
let test_bool = true;
set_string("demo.auto_save_test", test_value.to_string())?;
set_i64("demo.number", test_number)?;
set_bool("demo.enabled", test_bool)?;
let saved_value = get_string("demo.auto_save_test");
assert_eq!(saved_value, Some(test_value.to_string()), "自动保存的字符串值应该正确");
let saved_number = get_i64("demo.number");
assert_eq!(saved_number, Some(test_number), "自动保存的数字值应该正确");
let saved_bool = get_bool("demo.enabled");
assert_eq!(saved_bool, Some(test_bool), "自动保存的布尔值应该正确");
if let Some(_original_name) = get_string("app.name") {
let new_name = "更新后的应用名";
let result = set_string("app.name", new_name.to_string());
assert!(result.is_ok(), "修改配置文件中的值应该成功");
let updated_name = get_string("app.name");
assert_eq!(updated_name, Some(new_name.to_string()), "配置文件中的值应该被正确更新");
}
let new_host = "不应该被保存";
let result = set_string("database.host", new_host.to_string());
assert!(result.is_ok(), "修改数据库主机配置应该成功");
let updated_host = get_string("database.host");
assert!(updated_host.is_some(), "数据库主机配置应该存在");
Ok(())
}
#[test]
fn demo_config_manager() -> R {
let config_path = "test_config.toml";
let _ = init_config(config_path);
let prefix = "demo_manager";
set_string(&format!("{}.app.name", prefix), "tick_rhino".to_string())?;
set_bool(&format!("{}.app.debug", prefix), false)?;
set_string(&format!("{}.app.version", prefix), "1.0.0".to_string())?;
set_string(&format!("{}.database.host", prefix), "localhost".to_string())?;
set_i64(&format!("{}.database.port", prefix), 5432)?;
set_i64(&format!("{}.network.server_port", prefix), 8080)?;
set_i64(&format!("{}.network.max_connections", prefix), 100)?;
let app_name = get_string(&format!("{}.app.name", prefix)).unwrap();
let debug_mode = get_bool(&format!("{}.app.debug", prefix)).unwrap();
let server_port = get_i64(&format!("{}.network.server_port", prefix)).unwrap();
let db_port = get_i64(&format!("{}.database.port", prefix)).unwrap();
assert_eq!(app_name, "tick_rhino");
assert_eq!(debug_mode, false);
assert_eq!(server_port, 8080);
assert_eq!(db_port, 5432);
let host_value: Value = get_arg(&format!("{}.database.host", prefix));
assert_eq!(host_value, Value::String("localhost".to_string()));
let port_value: Value = get_arg(&format!("{}.database.port", prefix));
assert_eq!(port_value, Value::Number(serde_json::Number::from(5432)));
set_bool(&format!("{}.app.debug", prefix), true)?;
set_string(&format!("{}.app.version", prefix), "1.0.1".to_string())?;
set_i64(&format!("{}.network.max_connections", prefix), 200)?;
let new_debug = get_bool(&format!("{}.app.debug", prefix)).unwrap();
let new_version = get_string(&format!("{}.app.version", prefix)).unwrap();
let new_max_conn = get_i64(&format!("{}.network.max_connections", prefix)).unwrap();
assert_eq!(new_debug, true);
assert_eq!(new_version, "1.0.1");
assert_eq!(new_max_conn, 200);
save_config()?;
Ok(())
}
#[test]
fn test_config_demo() {
let config_path = "test_config.toml";
let _ = init_config(config_path);
let prefix = "test_demo";
set_string(&format!("{}.app.name", prefix), "test_demo_app".to_string()).unwrap();
set_bool(&format!("{}.app.debug", prefix), false).unwrap();
set_string(&format!("{}.app.version", prefix), "1.0.0".to_string()).unwrap();
set_string(&format!("{}.database.host", prefix), "localhost".to_string()).unwrap();
set_i64(&format!("{}.database.port", prefix), 5432).unwrap();
set_i64(&format!("{}.network.server_port", prefix), 8080).unwrap();
set_i64(&format!("{}.network.max_connections", prefix), 100).unwrap();
let app_name = get_string(&format!("{}.app.name", prefix)).unwrap();
let debug_mode = get_bool(&format!("{}.app.debug", prefix)).unwrap();
let server_port = get_i64(&format!("{}.network.server_port", prefix)).unwrap();
let db_host = get_string(&format!("{}.database.host", prefix)).unwrap();
let db_port = get_i64(&format!("{}.database.port", prefix)).unwrap();
assert_eq!(app_name, "test_demo_app");
assert_eq!(debug_mode, false);
assert_eq!(server_port, 8080);
assert_eq!(db_host, "localhost");
assert_eq!(db_port, 5432);
set_bool(&format!("{}.app.debug", prefix), true).unwrap();
set_i64(&format!("{}.network.max_connections", prefix), 200).unwrap();
set_string(&format!("{}.app.version", prefix), "2.0.0".to_string()).unwrap();
let new_debug = get_bool(&format!("{}.app.debug", prefix)).unwrap();
let new_max_conn = get_i64(&format!("{}.network.max_connections", prefix)).unwrap();
let new_version = get_string(&format!("{}.app.version", prefix)).unwrap();
assert_eq!(new_debug, true);
assert_eq!(new_max_conn, 200);
assert_eq!(new_version, "2.0.0");
save_config().unwrap();
}
#[test]
fn test_cross_module_access() {
let config_path = "test_config.toml";
let _ = init_config(config_path);
let prefix = "test_cross";
set_i64(&format!("{}.network.server_port", prefix), 8080).unwrap();
set_i64(&format!("{}.network.max_connections", prefix), 100).unwrap();
set_string(&format!("{}.app.name", prefix), "cross_module_test".to_string()).unwrap();
let initial_port = get_i64(&format!("{}.network.server_port", prefix)).unwrap();
let initial_max_conn = get_i64(&format!("{}.network.max_connections", prefix)).unwrap();
let app_name = get_string(&format!("{}.app.name", prefix)).unwrap();
assert_eq!(initial_port, 8080);
assert_eq!(initial_max_conn, 100);
assert_eq!(app_name, "cross_module_test");
let result = demo_cross_module_access();
assert_eq!(result.is_ok(), true);
let final_port = get_i64("cross_module.server_port").unwrap();
let final_max_conn = get_i64("cross_module.max_connections").unwrap();
assert_eq!(final_port, 8080); assert_eq!(final_max_conn, 500); }
#[test]
fn test_complex_config_operations() {
let config_path = "test_config.toml";
let _ = init_config(config_path);
let prefix = "test_complex";
set_string(&format!("{}.app.name", prefix), "complex_test_app".to_string()).unwrap();
set_string(&format!("{}.app.version", prefix), "1.0.0".to_string()).unwrap();
let app_name = get_string(&format!("{}.app.name", prefix)).unwrap();
let app_version = get_string(&format!("{}.app.version", prefix)).unwrap();
assert_eq!(app_name, "complex_test_app");
assert_eq!(app_version, "1.0.0");
let result = demo_complex_config();
assert_eq!(result.is_ok(), true);
let nested_value = get_string("complex_demo.nested.key").unwrap();
assert_eq!(nested_value, "nested_value");
let array_config = get_arg("complex_demo.test_array");
assert_eq!(array_config.is_array(), true);
let Value::Array(arr) = array_config else {
panic!("Expected array configuration");
};
assert_eq!(arr.len(), 3);
assert_eq!(arr[0], Value::String("item1".to_string()));
assert_eq!(arr[1], Value::String("item2".to_string()));
assert_eq!(arr[2], Value::Number(serde_json::Number::from(42)));
let object_config = get_arg("complex_demo.test_object");
assert_eq!(object_config.is_object(), true);
let Value::Object(obj) = object_config else {
panic!("Expected object configuration");
};
assert_eq!(obj.len(), 3);
assert_eq!(obj.get("name").unwrap(), &Value::String("test_object".to_string()));
assert_eq!(obj.get("count").unwrap(), &Value::Number(serde_json::Number::from(99)));
assert_eq!(obj.get("enabled").unwrap(), &Value::Bool(true));
save_config().unwrap();
}
}