use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize, Clone, Debug, Default)]
pub struct NotificationConfig {
#[serde(default)]
loop_armed: Option<String>,
#[serde(default)]
break_requested: Option<String>,
#[serde(default)]
loop_exited: Option<String>,
#[serde(default)]
section_entering: Option<String>,
#[serde(default)]
sections: HashMap<String, String>,
}
impl NotificationConfig {
pub fn event_overrides(&self) -> HashMap<String, String> {
let mut overrides = HashMap::new();
if let Some(ref path) = self.loop_armed {
overrides.insert("loop_armed".to_string(), path.clone());
}
if let Some(ref path) = self.break_requested {
overrides.insert("break_requested".to_string(), path.clone());
}
if let Some(ref path) = self.loop_exited {
overrides.insert("loop_exited".to_string(), path.clone());
}
if let Some(ref path) = self.section_entering {
overrides.insert("section_entering".to_string(), path.clone());
}
overrides
}
pub fn section_overrides(&self) -> &HashMap<String, String> {
&self.sections
}
}
pub type SongNotificationConfig = NotificationConfig;
#[cfg(test)]
mod tests {
use super::*;
use config::{Config, File, FileFormat};
#[test]
fn notification_config_defaults() {
let config = NotificationConfig::default();
assert!(config.event_overrides().is_empty());
assert!(config.section_overrides().is_empty());
}
#[test]
fn notification_config_serde() {
let yaml = r#"
loop_armed: /audio/armed.wav
break_requested: /audio/break.wav
sections:
verse: /audio/verse.wav
chorus: /audio/chorus.wav
"#;
let config: NotificationConfig = Config::builder()
.add_source(File::from_str(yaml, FileFormat::Yaml))
.build()
.unwrap()
.try_deserialize()
.unwrap();
let overrides = config.event_overrides();
assert_eq!(overrides.get("loop_armed").unwrap(), "/audio/armed.wav");
assert_eq!(
overrides.get("break_requested").unwrap(),
"/audio/break.wav"
);
assert!(!overrides.contains_key("loop_exited"));
let sections = config.section_overrides();
assert_eq!(sections.get("verse").unwrap(), "/audio/verse.wav");
assert_eq!(sections.get("chorus").unwrap(), "/audio/chorus.wav");
}
#[test]
fn song_notification_config_serde() {
let yaml = r#"
loop_armed: custom_armed.wav
sections:
intro: intro.wav
"#;
let config: SongNotificationConfig = Config::builder()
.add_source(File::from_str(yaml, FileFormat::Yaml))
.build()
.unwrap()
.try_deserialize()
.unwrap();
let overrides = config.event_overrides();
assert_eq!(overrides.get("loop_armed").unwrap(), "custom_armed.wav");
assert_eq!(overrides.len(), 1);
assert_eq!(
config.section_overrides().get("intro").unwrap(),
"intro.wav"
);
}
}