Support enabling multiple notification sinks (#344)

This commit is contained in:
Nemo157 2024-09-17 07:15:36 +02:00 committed by GitHub
parent e40a8a8d2e
commit 9a9bdb4862
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 106 additions and 18 deletions

View file

@ -398,23 +398,70 @@ pub enum UserDisplayStyle {
DisplayName,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum NotifyVia {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct NotifyVia {
/// Deliver notifications via terminal bell.
Bell,
pub bell: bool,
/// Deliver notifications via desktop mechanism.
#[cfg(feature = "desktop")]
Desktop,
pub desktop: bool,
}
pub struct NotifyViaVisitor;
impl Default for NotifyVia {
fn default() -> Self {
#[cfg(not(feature = "desktop"))]
return NotifyVia::Bell;
Self {
bell: cfg!(not(feature = "desktop")),
#[cfg(feature = "desktop")]
desktop: true,
}
}
}
#[cfg(feature = "desktop")]
return NotifyVia::Desktop;
impl<'de> Visitor<'de> for NotifyViaVisitor {
type Value = NotifyVia;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a valid notify destination (e.g. \"bell\" or \"desktop\")")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: SerdeError,
{
let mut via = NotifyVia {
bell: false,
#[cfg(feature = "desktop")]
desktop: false,
};
for value in value.split('|') {
match value.to_ascii_lowercase().as_str() {
"bell" => {
via.bell = true;
},
#[cfg(feature = "desktop")]
"desktop" => {
via.desktop = true;
},
#[cfg(not(feature = "desktop"))]
"desktop" => {
return Err(E::custom("desktop notification support was compiled out"))
},
_ => return Err(E::custom("could not parse into a notify destination")),
};
}
Ok(via)
}
}
impl<'de> Deserialize<'de> for NotifyVia {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(NotifyViaVisitor)
}
}
@ -1189,6 +1236,29 @@ mod tests {
assert_eq!(run, &exp);
}
#[test]
fn test_parse_notify_via() {
assert_eq!(NotifyVia { bell: false, desktop: true }, NotifyVia::default());
assert_eq!(
NotifyVia { bell: false, desktop: true },
serde_json::from_str(r#""desktop""#).unwrap()
);
assert_eq!(
NotifyVia { bell: true, desktop: false },
serde_json::from_str(r#""bell""#).unwrap()
);
assert_eq!(
NotifyVia { bell: true, desktop: true },
serde_json::from_str(r#""bell|desktop""#).unwrap()
);
assert_eq!(
NotifyVia { bell: true, desktop: true },
serde_json::from_str(r#""desktop|bell""#).unwrap()
);
assert!(serde_json::from_str::<NotifyVia>(r#""other""#).is_err());
assert!(serde_json::from_str::<NotifyVia>(r#""""#).is_err());
}
#[test]
fn test_load_example_config_toml() {
let path = PathBuf::from("config.example.toml");