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