1use core::fmt;
2use core::str::FromStr;
3
4use alloc::string::ToString;
5
6use crate::error::{HttpUrlError, Result};
7
8const DEFAULT_HTTP_PORT: u16 = 80;
10
11const DEFAULT_HTTPS_PORT: u16 = 443;
13
14#[derive(Copy, Clone, Debug, Eq, PartialEq)]
16pub enum Scheme {
17 Http,
19 Https,
21}
22
23impl Scheme {
24 pub fn as_str(&self) -> &'static str {
26 match self {
27 Self::Http => "http",
28 Self::Https => "https",
29 }
30 }
31
32 pub fn default_port(&self) -> u16 {
34 match self {
35 Self::Http => DEFAULT_HTTP_PORT,
36 Self::Https => DEFAULT_HTTPS_PORT,
37 }
38 }
39}
40
41impl FromStr for Scheme {
42 type Err = HttpUrlError;
43
44 fn from_str(s: &str) -> Result<Self> {
45 match s {
46 "http" => Ok(Self::Http),
47 "https" => Ok(Self::Https),
48 other => Err(HttpUrlError::UnsupportedScheme(other.to_string())),
49 }
50 }
51}
52
53impl fmt::Display for Scheme {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 f.write_str(self.as_str())
56 }
57}
58
59impl AsRef<str> for Scheme {
60 fn as_ref(&self) -> &str {
61 self.as_str()
62 }
63}
64
65impl PartialEq<&str> for Scheme {
66 fn eq(&self, other: &&str) -> bool {
67 self.as_str() == *other
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use alloc::format;
75
76 #[test]
77 fn display() {
78 assert_eq!(format!("{}", Scheme::Http), "http");
79 assert_eq!(format!("{}", Scheme::Https), "https");
80 }
81
82 #[test]
83 fn as_ref() {
84 assert_eq!(Scheme::Http.as_ref(), "http");
85 assert_eq!(Scheme::Https.as_ref(), "https");
86 }
87
88 #[test]
89 fn from_str() {
90 assert_eq!("http".parse::<Scheme>().unwrap(), Scheme::Http);
91 assert_eq!("https".parse::<Scheme>().unwrap(), Scheme::Https);
92 assert_eq!(
93 "ftp".parse::<Scheme>().unwrap_err(),
94 HttpUrlError::UnsupportedScheme("ftp".to_string())
95 );
96 }
97
98 #[test]
99 fn default_port() {
100 assert_eq!(Scheme::Http.default_port(), 80);
101 assert_eq!(Scheme::Https.default_port(), 443);
102 }
103}