pub mod config;
#[macro_export]
macro_rules! read_config {
() => {
$crate::config::get_config()
};
($key:expr) => {
$crate::config::get_config_by_key($key)
};
($key:expr, $t:ty) => {{
let value_opt = $crate::config::get_config_by_key($key);
match value_opt {
Some(v) => match serde_json::from_value::<$t>(v) {
Ok(val) => Some(val),
Err(err) => {
eprintln!(
"Failed to parse config key {} into type {}: {:?}",
$key,
stringify!($t),
err
);
None
}
},
None => None,
}
}};
}
#[macro_export]
macro_rules! register_config {
($namespace:expr, $config:expr) => {{
$crate::config::register_config($namespace, $config);
}};
}
#[cfg(test)]
mod tests {
use super::*;
use serde::Serialize;
use serde_json::{Value, json};
#[derive(Serialize)]
struct DummyConfig {
port: u16,
host: String,
}
fn setup() {
config::init_config();
}
#[test]
fn test_register_and_read_full_config() {
setup();
register_config!(
"server",
DummyConfig {
port: 3000,
host: "0.0.0.0".into()
}
);
let full = read_config!();
if let Value::Object(map) = full {
assert!(
map.contains_key("server"),
"Expected key 'server' not found"
);
if let Some(Value::Object(server_obj)) = map.get("server") {
assert_eq!(server_obj.get("port").unwrap(), &json!(3000));
assert_eq!(server_obj.get("host").unwrap(), &json!("0.0.0.0"));
} else {
panic!("'server' is not an object");
}
} else {
panic!("Global config is not an object");
}
}
#[test]
fn test_read_config_by_key() {
setup();
let port = read_config!("server.port");
assert_eq!(port, Some(json!(3000)));
let host = read_config!("server.host");
assert_eq!(host, Some(json!("0.0.0.0")));
let missing = read_config!("server.nonexistent");
assert!(missing.is_none());
}
}