use crate::domain::{ConfigKey, ConfigValue, Result};
pub trait ConfigSource: Send + Sync {
fn name(&self) -> &str;
fn priority(&self) -> u8;
fn get(&self, key: &ConfigKey) -> Result<Option<ConfigValue>>;
fn all_keys(&self) -> Result<Vec<ConfigKey>>;
fn reload(&mut self) -> Result<()>;
fn get_str(&self, key: &str) -> Result<Option<ConfigValue>> {
self.get(&ConfigKey::from(key))
}
}
#[cfg(test)]
mod tests {
use super::*;
struct TestSource {
name: String,
priority: u8,
}
impl ConfigSource for TestSource {
fn name(&self) -> &str {
&self.name
}
fn priority(&self) -> u8 {
self.priority
}
fn get(&self, _key: &ConfigKey) -> Result<Option<ConfigValue>> {
Ok(None)
}
fn all_keys(&self) -> Result<Vec<ConfigKey>> {
Ok(vec![])
}
fn reload(&mut self) -> Result<()> {
Ok(())
}
}
#[test]
fn test_config_source_name() {
let source = TestSource {
name: "test-source".to_string(),
priority: 1,
};
assert_eq!(source.name(), "test-source");
}
#[test]
fn test_config_source_priority() {
let source = TestSource {
name: "test-source".to_string(),
priority: 2,
};
assert_eq!(source.priority(), 2);
}
#[test]
fn test_config_source_get_returns_none() {
let source = TestSource {
name: "test-source".to_string(),
priority: 1,
};
let key = ConfigKey::from("nonexistent");
let result = source.get(&key).unwrap();
assert!(result.is_none());
}
#[test]
fn test_config_source_all_keys_empty() {
let source = TestSource {
name: "test-source".to_string(),
priority: 1,
};
let keys = source.all_keys().unwrap();
assert_eq!(keys.len(), 0);
}
#[test]
fn test_config_source_reload() {
let mut source = TestSource {
name: "test-source".to_string(),
priority: 1,
};
assert!(source.reload().is_ok());
}
#[test]
fn test_config_source_is_send_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<Box<dyn ConfigSource>>();
}
}