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 | | } |