1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
4#[serde(rename_all = "lowercase")]
5pub enum Level {
6 Error,
7 Warning,
8 Info,
9 Off,
10}
11
12impl Level {
13 pub fn is_actionable(self) -> bool {
14 matches!(self, Self::Error | Self::Warning | Self::Info)
15 }
16
17 pub fn as_str(self) -> &'static str {
18 match self {
19 Self::Error => "error",
20 Self::Warning => "warning",
21 Self::Info => "info",
22 Self::Off => "off",
23 }
24 }
25}
26
27#[cfg(test)]
28mod tests {
29 use super::*;
30
31 #[test]
32 fn is_actionable_returns_true_for_emitted_severities() {
33 assert!(Level::Error.is_actionable());
34 assert!(Level::Warning.is_actionable());
35 assert!(Level::Info.is_actionable());
36 }
37
38 #[test]
39 fn is_actionable_returns_false_for_off() {
40 assert!(!Level::Off.is_actionable());
45 }
46
47 #[test]
48 fn as_str_round_trips_with_serde_lowercase_rename() {
49 assert_eq!(Level::Error.as_str(), "error");
50 assert_eq!(Level::Warning.as_str(), "warning");
51 assert_eq!(Level::Info.as_str(), "info");
52 assert_eq!(Level::Off.as_str(), "off");
53 }
54
55 #[derive(serde::Deserialize)]
56 struct Wrap {
57 level: Level,
58 }
59
60 #[test]
61 fn deserializes_from_lowercase_yaml_string() {
62 let yaml = "level: warning\n";
63 let w: Wrap = serde_yaml_ng::from_str(yaml).unwrap();
64 assert_eq!(w.level, Level::Warning);
65 }
66
67 #[test]
68 fn rejects_uppercase_yaml_string() {
69 let yaml = "level: Error\n";
74 assert!(serde_yaml_ng::from_str::<Wrap>(yaml).is_err());
75 }
76}