use tracing::info;
use crate::error::PluginError;
use crate::traits::CancellationToken;
use super::wake::{WakeWordConfig, WakeWordDetector};
pub struct WakeDaemon {
detector: WakeWordDetector,
active: bool,
}
impl WakeDaemon {
pub fn new(config: WakeWordConfig) -> Result<Self, PluginError> {
let detector = WakeWordDetector::new(config)?;
Ok(Self {
detector,
active: false,
})
}
#[cfg(not(target_arch = "wasm32"))]
pub async fn run(&mut self, cancel: CancellationToken) -> Result<(), PluginError> {
info!("wake daemon started (stub)");
self.active = true;
self.detector.start();
cancel.cancelled().await;
self.detector.stop();
self.active = false;
info!("wake daemon stopped");
Ok(())
}
pub fn is_active(&self) -> bool {
self.active
}
pub fn detector(&self) -> &WakeWordDetector {
&self.detector
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn wake_daemon_create() {
let config = WakeWordConfig::default();
let daemon = WakeDaemon::new(config).unwrap();
assert!(!daemon.is_active());
}
#[test]
fn wake_daemon_detector_access() {
let config = WakeWordConfig {
threshold: 0.3,
..Default::default()
};
let daemon = WakeDaemon::new(config).unwrap();
assert!((daemon.detector().config().threshold - 0.3).abs() < f32::EPSILON);
}
#[tokio::test]
async fn wake_daemon_run_and_cancel() {
let config = WakeWordConfig::default();
let mut daemon = WakeDaemon::new(config).unwrap();
let cancel = CancellationToken::new();
let cancel_clone = cancel.clone();
let handle = tokio::spawn(async move { daemon.run(cancel_clone).await });
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
cancel.cancel();
let result = handle.await.unwrap();
assert!(result.is_ok());
}
}