Skip to main content

openvpn_mgmt_codec/
status_format.rs

1use std::str::FromStr;
2
3/// Error returned when a string is not a recognized status format.
4#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
5#[error("unrecognized status format: {0:?}")]
6pub struct ParseStatusFormatError(pub String);
7
8/// Status output format version. Higher versions are more machine-parseable.
9///
10/// - V1: default human-readable format
11/// - V2: adds header/footer markers for easier parsing
12/// - V3: tab-delimited, ideal for programmatic consumption
13#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, strum::Display)]
14pub enum StatusFormat {
15    /// Default human-readable format.
16    #[default]
17    #[strum(to_string = "1")]
18    V1,
19
20    /// Adds header/footer markers for easier parsing.
21    #[strum(to_string = "2")]
22    V2,
23
24    /// Tab-delimited, ideal for programmatic consumption.
25    #[strum(to_string = "3")]
26    V3,
27}
28
29impl FromStr for StatusFormat {
30    type Err = ParseStatusFormatError;
31
32    /// Parse a status format version: `1`, `2`, or `3`.
33    fn from_str(input: &str) -> Result<Self, Self::Err> {
34        match input {
35            "1" => Ok(Self::V1),
36            "2" => Ok(Self::V2),
37            "3" => Ok(Self::V3),
38            other => Err(ParseStatusFormatError(other.to_string())),
39        }
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46    use test_case::test_case;
47
48    #[test_case(StatusFormat::V1)]
49    #[test_case(StatusFormat::V2)]
50    #[test_case(StatusFormat::V3)]
51    fn display_roundtrip(fmt: StatusFormat) {
52        let string = fmt.to_string();
53        assert_eq!(string.parse::<StatusFormat>().unwrap(), fmt);
54    }
55
56    #[test]
57    fn display_values() {
58        assert_eq!(StatusFormat::V1.to_string(), "1");
59        assert_eq!(StatusFormat::V2.to_string(), "2");
60        assert_eq!(StatusFormat::V3.to_string(), "3");
61    }
62
63    #[test]
64    fn parse_invalid() {
65        assert!("4".parse::<StatusFormat>().is_err());
66        assert!("".parse::<StatusFormat>().is_err());
67    }
68}