mit_commit_message_lints/mit/lib/
rotation_option.rs1use std::{
3 fmt::{Display, Formatter},
4 str::FromStr,
5};
6
7use crate::mit::lib::errors::DeserializeRotationOptionError;
8
9#[derive(clap::ValueEnum, Ord, PartialOrd, Eq, PartialEq, Debug, Clone, Copy)]
11pub enum RotationOption {
12 Off,
14 RoundRobin,
16 Random,
18}
19
20const OFF_DISPLAY: &str = "off";
21const ROUND_ROBIN_DISPLAY: &str = "round-robin";
22const RANDOM_DISPLAY: &str = "random";
23
24impl FromStr for RotationOption {
25 type Err = DeserializeRotationOptionError;
26
27 fn from_str(s: &str) -> Result<Self, Self::Err> {
28 match s.to_ascii_lowercase().as_str() {
29 OFF_DISPLAY => Ok(Self::Off),
30 ROUND_ROBIN_DISPLAY => Ok(Self::RoundRobin),
31 RANDOM_DISPLAY => Ok(Self::Random),
32 _ => Err(DeserializeRotationOptionError { src: s.into() }),
33 }
34 }
35}
36
37impl Display for RotationOption {
38 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
39 match self {
40 Self::Off => write!(f, "{OFF_DISPLAY}"),
41 Self::RoundRobin => write!(f, "{ROUND_ROBIN_DISPLAY}"),
42 Self::Random => write!(f, "{RANDOM_DISPLAY}"),
43 }
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use std::str::FromStr;
50
51 use super::RotationOption;
52
53 #[test]
54 fn from_str_accepts_lowercase() {
55 assert_eq!(
56 RotationOption::from_str("round-robin").unwrap(),
57 RotationOption::RoundRobin,
58 "Expected 'round-robin' to parse as RoundRobin"
59 );
60 }
61
62 #[test]
63 fn from_str_rejects_unknown() {
64 assert!(
65 RotationOption::from_str("unknown").is_err(),
66 "Expected parsing an unknown rotation option to return an error"
67 );
68 }
69
70 #[test]
71 fn from_str_is_case_insensitive_like_value_enum() {
72 assert_eq!(
73 RotationOption::from_str("Round-Robin").unwrap(),
74 RotationOption::RoundRobin,
75 "Expected 'Round-Robin' to parse as RoundRobin (case insensitive)"
76 );
77 assert_eq!(
78 RotationOption::from_str("ROUND-ROBIN").unwrap(),
79 RotationOption::RoundRobin,
80 "Expected 'ROUND-ROBIN' to parse as RoundRobin (case insensitive)"
81 );
82 }
83
84 #[test]
85 fn from_str_accepts_random() {
86 assert_eq!(
87 RotationOption::from_str("random").unwrap(),
88 RotationOption::Random,
89 "Expected 'random' to parse as Random"
90 );
91 }
92
93 #[test]
94 fn from_str_accepts_random_case_insensitive() {
95 assert_eq!(
96 RotationOption::from_str("Random").unwrap(),
97 RotationOption::Random,
98 "Expected 'Random' to parse as Random (case insensitive)"
99 );
100 assert_eq!(
101 RotationOption::from_str("RANDOM").unwrap(),
102 RotationOption::Random,
103 "Expected 'RANDOM' to parse as Random (case insensitive)"
104 );
105 }
106
107 #[test]
108 fn display_round_trips_through_from_str() {
109 for original in [
110 RotationOption::Off,
111 RotationOption::RoundRobin,
112 RotationOption::Random,
113 ] {
114 let displayed = original.to_string();
115 let parsed = RotationOption::from_str(&displayed);
116 assert_eq!(
117 parsed.unwrap(),
118 original,
119 "Expected display output to round-trip through from_str"
120 );
121 }
122 }
123
124 #[test]
125 fn display_random_round_trips() {
126 let original = RotationOption::Random;
127 let displayed = original.to_string();
128 let parsed = RotationOption::from_str(&displayed);
129 assert_eq!(
130 parsed.unwrap(),
131 original,
132 "Expected Random display output to round-trip through from_str"
133 );
134 }
135}