Skip to main content

kellnr_settings/
protocol.rs

1use clap::ValueEnum;
2use serde::{Deserialize, Deserializer, Serialize};
3
4use crate::deserialize_with::DeserializeWith;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, ValueEnum)]
7pub enum Protocol {
8    #[default]
9    Http,
10    Https,
11}
12
13impl std::fmt::Display for Protocol {
14    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15        match self {
16            Protocol::Http => write!(f, "http"),
17            Protocol::Https => write!(f, "https"),
18        }
19    }
20}
21
22impl<'de> Deserialize<'de> for Protocol {
23    fn deserialize<D>(de: D) -> Result<Self, D::Error>
24    where
25        D: Deserializer<'de>,
26    {
27        Protocol::deserialize_with(de)
28    }
29}
30
31impl DeserializeWith for Protocol {
32    fn deserialize_with<'de, D>(de: D) -> Result<Self, D::Error>
33    where
34        D: Deserializer<'de>,
35    {
36        let s = String::deserialize(de)?.to_lowercase();
37
38        match s.as_ref() {
39            "http" => Ok(Protocol::Http),
40            "https" => Ok(Protocol::Https),
41            _ => Err(serde::de::Error::custom(
42                "error trying to deserialize protocol config",
43            )),
44        }
45    }
46}
47
48impl Serialize for Protocol {
49    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
50    where
51        S: serde::Serializer,
52    {
53        match self {
54            Protocol::Http => serializer.serialize_str("http"),
55            Protocol::Https => serializer.serialize_str("https"),
56        }
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use serde::Deserialize;
63
64    use super::*;
65
66    #[test]
67    fn test_protocol_display() {
68        assert_eq!(Protocol::Http.to_string(), "http");
69        assert_eq!(Protocol::Https.to_string(), "https");
70    }
71
72    #[derive(Debug, Deserialize)]
73    struct Settings {
74        #[serde(deserialize_with = "Protocol::deserialize_with")]
75        protocol: Protocol,
76    }
77
78    #[test]
79    fn test_deserialize_protocol_https() {
80        let toml = r#"
81            protocol = "https"
82        "#;
83
84        let settings: Settings = toml::from_str(toml).unwrap();
85        assert_eq!(settings.protocol, Protocol::Https);
86    }
87
88    #[test]
89    fn test_deserialize_protocol_http() {
90        let toml = r#"
91            protocol = "http"
92        "#;
93
94        let settings: Settings = toml::from_str(toml).unwrap();
95        assert_eq!(settings.protocol, Protocol::Http);
96    }
97
98    #[test]
99    fn test_deserialize_protocol_uppercase() {
100        let toml = r#"
101            protocol = "HTTPS"
102        "#;
103
104        let settings: Settings = toml::from_str(toml).unwrap();
105        assert_eq!(settings.protocol, Protocol::Https);
106    }
107
108    #[test]
109    fn test_deserialize_protocol_error() {
110        let toml = r#"
111            protocol = "ftp"
112        "#;
113
114        let settings: Result<Settings, toml::de::Error> = toml::from_str(toml);
115        assert!(settings.is_err());
116    }
117
118    #[test]
119    fn test_serialize_protocol_http() {
120        let protocol = Protocol::Http;
121        let json = serde_json::to_string(&protocol).unwrap();
122        assert_eq!(json, r#""http""#);
123    }
124
125    #[test]
126    fn test_serialize_protocol_https() {
127        let protocol = Protocol::Https;
128        let json = serde_json::to_string(&protocol).unwrap();
129        assert_eq!(json, r#""https""#);
130    }
131}