1use std::fmt;
4use std::str::FromStr;
5
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
10#[serde(rename_all = "snake_case")]
11pub enum AdrStatus {
12 Proposed,
14 Accepted,
16 Deprecated,
18 Superseded,
20}
21
22impl AdrStatus {
23 #[must_use]
25 pub const fn display_name(&self) -> &'static str {
26 match self {
27 Self::Proposed => "Proposed",
28 Self::Accepted => "Accepted",
29 Self::Deprecated => "Deprecated",
30 Self::Superseded => "Superseded",
31 }
32 }
33
34 #[must_use]
36 pub const fn as_str(&self) -> &'static str {
37 match self {
38 Self::Proposed => "proposed",
39 Self::Accepted => "accepted",
40 Self::Deprecated => "deprecated",
41 Self::Superseded => "superseded",
42 }
43 }
44}
45
46impl fmt::Display for AdrStatus {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 write!(f, "{}", self.display_name())
49 }
50}
51
52impl FromStr for AdrStatus {
53 type Err = String;
54
55 fn from_str(s: &str) -> Result<Self, Self::Err> {
56 match s.to_lowercase().as_str() {
57 "proposed" => Ok(Self::Proposed),
58 "accepted" => Ok(Self::Accepted),
59 "deprecated" => Ok(Self::Deprecated),
60 "superseded" => Ok(Self::Superseded),
61 _ => Err(format!(
62 "Invalid ADR status '{s}'. Expected one of: proposed, accepted, deprecated, superseded"
63 )),
64 }
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn test_adr_status_display() {
74 assert_eq!(AdrStatus::Proposed.to_string(), "Proposed");
75 assert_eq!(AdrStatus::Accepted.to_string(), "Accepted");
76 assert_eq!(AdrStatus::Deprecated.to_string(), "Deprecated");
77 assert_eq!(AdrStatus::Superseded.to_string(), "Superseded");
78 }
79
80 #[test]
81 fn test_adr_status_from_str() {
82 assert_eq!(
83 "proposed".parse::<AdrStatus>().unwrap(),
84 AdrStatus::Proposed
85 );
86 assert_eq!(
87 "ACCEPTED".parse::<AdrStatus>().unwrap(),
88 AdrStatus::Accepted
89 );
90 assert!("invalid".parse::<AdrStatus>().is_err());
91 }
92
93 #[test]
94 fn test_adr_status_as_str() {
95 assert_eq!(AdrStatus::Proposed.as_str(), "proposed");
96 assert_eq!(AdrStatus::Superseded.as_str(), "superseded");
97 }
98}