Coverage Report

Created: 2026-09-05 23:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
super-stt-shared/src/models/notification_method.rs
Line
Count
Source
1
// SPDX-License-Identifier: GPL-3.0-only
2
3
use super::wire_enum::wire_enum_strings;
4
5
/// How the daemon surfaces a recording failure to the user.
6
///
7
/// The caller always learns about a failure through the response and the
8
/// `error` event; this controls the additional human-facing notice.
9
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
10
pub enum NotificationMethod {
11
    /// Desktop notification, falling back to typing the notice if it cannot
12
    /// be delivered.
13
    #[default]
14
    Auto,
15
    /// Desktop notification only; log if it cannot be delivered.
16
    Dbus,
17
    /// Type a fixed notice into the focused window.
18
    Typed,
19
    /// Log only; never surface.
20
    Off,
21
}
22
23
wire_enum_strings!(NotificationMethod {
24
    Auto => "auto",
25
    Dbus => "dbus",
26
    Typed => "typed",
27
    Off => "off",
28
});
29
30
impl NotificationMethod {
31
    #[must_use]
32
0
    pub fn pretty_name(self) -> &'static str {
33
0
        match self {
34
0
            Self::Auto => "Auto (recommended)",
35
0
            Self::Dbus => "Desktop notification",
36
0
            Self::Typed => "Type into window",
37
0
            Self::Off => "Off",
38
        }
39
0
    }
40
}
41
42
#[cfg(test)]
43
mod tests {
44
    use super::*;
45
46
    #[test]
47
2
    fn default_is_auto() {
48
2
        assert_eq!(NotificationMethod::default(), NotificationMethod::Auto);
49
2
    }
50
51
    #[test]
52
2
    fn display_roundtrip() {
53
8
        for method in [
54
2
            NotificationMethod::Auto,
55
2
            NotificationMethod::Dbus,
56
2
            NotificationMethod::Typed,
57
2
            NotificationMethod::Off,
58
2
        ] {
59
8
            let s = method.to_string();
60
8
            let parsed: NotificationMethod = s.parse().unwrap();
61
8
            assert_eq!(parsed, method);
62
        }
63
2
    }
64
65
    #[test]
66
2
    fn wire_tokens_are_snake_case() {
67
2
        assert_eq!(NotificationMethod::Auto.to_string(), "auto");
68
2
        assert_eq!(NotificationMethod::Dbus.to_string(), "dbus");
69
2
        assert_eq!(NotificationMethod::Typed.to_string(), "typed");
70
2
        assert_eq!(NotificationMethod::Off.to_string(), "off");
71
2
    }
72
73
    #[test]
74
2
    fn from_str_rejects_unknown_and_plausible_aliases() {
75
2
        assert!("nonsense".parse::<NotificationMethod>().is_err());
76
        // No aliases: exactly one token maps to each variant.
77
14
        for dropped in [
78
2
            "notification",
79
2
            "notify",
80
2
            "d-bus",
81
2
            "freedesktop",
82
2
            "none",
83
2
            "disabled",
84
2
            "Auto",
85
2
        ] {
86
14
            assert!(
87
14
                dropped.parse::<NotificationMethod>().is_err(),
88
                "`{dropped}` must not parse"
89
            );
90
        }
91
2
    }
92
93
    #[test]
94
2
    fn serde_roundtrip() {
95
2
        let method = NotificationMethod::Dbus;
96
2
        let json = serde_json::to_string(&method).unwrap();
97
2
        assert_eq!(json, "\"dbus\"");
98
2
        let parsed: NotificationMethod = serde_json::from_str(&json).unwrap();
99
2
        assert_eq!(parsed, method);
100
2
    }
101
102
    #[test]
103
2
    fn wire_variants_lists_every_token() {
104
2
        assert_eq!(
105
            NotificationMethod::WIRE_VARIANTS,
106
            &["auto", "dbus", "typed", "off"]
107
        );
108
2
    }
109
}