1use http::Uri;
4
5pub trait UriExt {
7 fn host_str(&self) -> Option<&str>;
9
10 fn port_or_default(&self) -> Option<u16>;
12
13 fn is_https(&self) -> bool;
15
16 fn is_http(&self) -> bool;
18
19 fn origin(&self) -> Option<String>;
21}
22
23impl UriExt for Uri {
24 fn host_str(&self) -> Option<&str> {
25 self.host()
26 }
27
28 fn port_or_default(&self) -> Option<u16> {
29 if let Some(port) = self.port_u16() {
30 return Some(port);
31 }
32 match self.scheme_str() {
33 Some("https") => Some(443),
34 Some("http") => Some(80),
35 _ => None,
36 }
37 }
38
39 fn is_https(&self) -> bool {
40 self.scheme_str() == Some("https")
41 }
42
43 fn is_http(&self) -> bool {
44 self.scheme_str() == Some("http")
45 }
46
47 fn origin(&self) -> Option<String> {
48 let scheme = self.scheme_str()?;
49 let authority = self.authority()?.as_str();
50 Some(format!("{scheme}://{authority}"))
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57 use std::str::FromStr;
58
59 #[test]
60 fn test_host() {
61 let uri = Uri::from_str("http://example.com/path").expect("parse");
62 assert_eq!(uri.host_str(), Some("example.com"));
63 }
64
65 #[test]
66 fn test_port_or_default_http() {
67 let uri = Uri::from_str("http://example.com/path").expect("parse");
68 assert_eq!(uri.port_or_default(), Some(80));
69 }
70
71 #[test]
72 fn test_port_or_default_https() {
73 let uri = Uri::from_str("https://example.com/path").expect("parse");
74 assert_eq!(uri.port_or_default(), Some(443));
75 }
76
77 #[test]
78 fn test_port_or_default_explicit() {
79 let uri = Uri::from_str("http://example.com:8080/path").expect("parse");
80 assert_eq!(uri.port_or_default(), Some(8080));
81 }
82
83 #[test]
84 fn test_is_https() {
85 let uri = Uri::from_str("https://example.com").expect("parse");
86 assert!(uri.is_https());
87 assert!(!uri.is_http());
88 }
89
90 #[test]
91 fn test_is_http() {
92 let uri = Uri::from_str("http://example.com").expect("parse");
93 assert!(uri.is_http());
94 assert!(!uri.is_https());
95 }
96
97 #[test]
98 fn test_origin() {
99 let uri = Uri::from_str("https://example.com:8443/path?q=1").expect("parse");
100 assert_eq!(uri.origin(), Some("https://example.com:8443".to_string()));
101 }
102
103 #[test]
104 fn test_no_scheme() {
105 let uri = Uri::from_str("/path/only").expect("parse");
106 assert_eq!(uri.port_or_default(), None);
107 assert!(!uri.is_http());
108 assert!(!uri.is_https());
109 assert!(uri.origin().is_none());
110 }
111}