actix_tls/connect/
host.rs

1//! The [`Host`] trait.
2
3/// An interface for types where host parts (hostname and port) can be derived.
4///
5/// The [WHATWG URL Standard] defines the terminology used for this trait and its methods.
6///
7/// ```plain
8/// +------------------------+
9/// |          host          |
10/// +-----------------+------+
11/// |    hostname     | port |
12/// |                 |      |
13/// | sub.example.com : 8080 |
14/// +-----------------+------+
15/// ```
16///
17/// [WHATWG URL Standard]: https://url.spec.whatwg.org/
18pub trait Host: Unpin + 'static {
19    /// Extract hostname.
20    fn hostname(&self) -> &str;
21
22    /// Extract optional port.
23    fn port(&self) -> Option<u16> {
24        None
25    }
26}
27
28impl Host for String {
29    fn hostname(&self) -> &str {
30        self.split_once(':')
31            .map(|(hostname, _)| hostname)
32            .unwrap_or(self)
33    }
34
35    fn port(&self) -> Option<u16> {
36        self.split_once(':').and_then(|(_, port)| port.parse().ok())
37    }
38}
39
40impl Host for &'static str {
41    fn hostname(&self) -> &str {
42        self.split_once(':')
43            .map(|(hostname, _)| hostname)
44            .unwrap_or(self)
45    }
46
47    fn port(&self) -> Option<u16> {
48        self.split_once(':').and_then(|(_, port)| port.parse().ok())
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    macro_rules! assert_connection_info_eq {
57        ($req:expr, $hostname:expr, $port:expr) => {{
58            assert_eq!($req.hostname(), $hostname);
59            assert_eq!($req.port(), $port);
60        }};
61    }
62
63    #[test]
64    fn host_parsing() {
65        assert_connection_info_eq!("example.com", "example.com", None);
66        assert_connection_info_eq!("example.com:8080", "example.com", Some(8080));
67        assert_connection_info_eq!("example:8080", "example", Some(8080));
68        assert_connection_info_eq!("example.com:false", "example.com", None);
69        assert_connection_info_eq!("example.com:false:false", "example.com", None);
70    }
71}