use crate::domain::{ConfigKey, Result};
use std::sync::Arc;
pub type ChangeCallback = Arc<dyn Fn(ConfigKey) + Send + Sync>;
pub trait ConfigWatcher: Send + Sync {
fn watch(&mut self, callback: ChangeCallback) -> Result<()>;
fn stop(&mut self) -> Result<()>;
}
#[cfg(test)]
mod tests {
use super::*;
struct TestWatcher {
is_watching: bool,
}
impl TestWatcher {
fn new() -> Self {
TestWatcher { is_watching: false }
}
}
impl ConfigWatcher for TestWatcher {
fn watch(&mut self, _callback: ChangeCallback) -> Result<()> {
self.is_watching = true;
Ok(())
}
fn stop(&mut self) -> Result<()> {
self.is_watching = false;
Ok(())
}
}
#[test]
fn test_watcher_watch() {
let mut watcher = TestWatcher::new();
let callback = Arc::new(|_key: ConfigKey| {});
assert!(watcher.watch(callback).is_ok());
assert!(watcher.is_watching);
}
#[test]
fn test_watcher_stop() {
let mut watcher = TestWatcher::new();
watcher.is_watching = true;
assert!(watcher.stop().is_ok());
assert!(!watcher.is_watching);
}
#[test]
fn test_watcher_callback_invocation() {
use std::sync::Mutex;
let mut watcher = TestWatcher::new();
let invoked = Arc::new(Mutex::new(false));
let invoked_clone = invoked.clone();
let callback = Arc::new(move |_key: ConfigKey| {
*invoked_clone.lock().unwrap() = true;
});
watcher.watch(callback.clone()).unwrap();
callback(ConfigKey::from("test.key"));
assert!(*invoked.lock().unwrap());
}
#[test]
fn test_watcher_is_send_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<Box<dyn ConfigWatcher>>();
}
}