Coverage Report

Created: 2025-07-18 06:42

/src/http/src/uri/port.rs
Line
Count
Source (jump to first uncovered line)
1
use std::fmt;
2
3
use super::{ErrorKind, InvalidUri};
4
5
/// The port component of a URI.
6
pub struct Port<T> {
7
    port: u16,
8
    repr: T,
9
}
10
11
impl<T> Port<T> {
12
    /// Returns the port number as a `u16`.
13
    ///
14
    /// # Examples
15
    ///
16
    /// Port as `u16`.
17
    ///
18
    /// ```
19
    /// # use http::uri::Authority;
20
    /// let authority: Authority = "example.org:80".parse().unwrap();
21
    ///
22
    /// let port = authority.port().unwrap();
23
    /// assert_eq!(port.as_u16(), 80);
24
    /// ```
25
0
    pub const fn as_u16(&self) -> u16 {
26
0
        self.port
27
0
    }
28
}
29
30
impl<T> Port<T>
31
where
32
    T: AsRef<str>,
33
{
34
    /// Converts a `str` to a port number.
35
    ///
36
    /// The supplied `str` must be a valid u16.
37
0
    pub(crate) fn from_str(bytes: T) -> Result<Self, InvalidUri> {
38
0
        bytes
39
0
            .as_ref()
40
0
            .parse::<u16>()
41
0
            .map(|port| Port { port, repr: bytes })
42
0
            .map_err(|_| ErrorKind::InvalidPort.into())
43
0
    }
44
45
    /// Returns the port number as a `str`.
46
    ///
47
    /// # Examples
48
    ///
49
    /// Port as `str`.
50
    ///
51
    /// ```
52
    /// # use http::uri::Authority;
53
    /// let authority: Authority = "example.org:80".parse().unwrap();
54
    ///
55
    /// let port = authority.port().unwrap();
56
    /// assert_eq!(port.as_str(), "80");
57
    /// ```
58
0
    pub fn as_str(&self) -> &str {
59
0
        self.repr.as_ref()
60
0
    }
61
}
62
63
impl<T> fmt::Debug for Port<T>
64
where
65
    T: fmt::Debug,
66
{
67
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68
0
        f.debug_tuple("Port").field(&self.port).finish()
69
0
    }
70
}
71
72
impl<T> fmt::Display for Port<T> {
73
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74
0
        // Use `u16::fmt` so that it respects any formatting flags that
75
0
        // may have been set (like padding, align, etc).
76
0
        fmt::Display::fmt(&self.port, f)
77
0
    }
78
}
79
80
impl<T> From<Port<T>> for u16 {
81
0
    fn from(port: Port<T>) -> Self {
82
0
        port.as_u16()
83
0
    }
84
}
85
86
impl<T> AsRef<str> for Port<T>
87
where
88
    T: AsRef<str>,
89
{
90
0
    fn as_ref(&self) -> &str {
91
0
        self.as_str()
92
0
    }
93
}
94
95
impl<T, U> PartialEq<Port<U>> for Port<T> {
96
0
    fn eq(&self, other: &Port<U>) -> bool {
97
0
        self.port == other.port
98
0
    }
99
}
100
101
impl<T> PartialEq<u16> for Port<T> {
102
0
    fn eq(&self, other: &u16) -> bool {
103
0
        self.port == *other
104
0
    }
105
}
106
107
impl<T> PartialEq<Port<T>> for u16 {
108
0
    fn eq(&self, other: &Port<T>) -> bool {
109
0
        other.port == *self
110
0
    }
111
}
112
113
#[cfg(test)]
114
mod tests {
115
    use super::*;
116
117
    #[test]
118
    fn partialeq_port() {
119
        let port_a = Port::from_str("8080").unwrap();
120
        let port_b = Port::from_str("8080").unwrap();
121
        assert_eq!(port_a, port_b);
122
    }
123
124
    #[test]
125
    fn partialeq_port_different_reprs() {
126
        let port_a = Port {
127
            repr: "8081",
128
            port: 8081,
129
        };
130
        let port_b = Port {
131
            repr: String::from("8081"),
132
            port: 8081,
133
        };
134
        assert_eq!(port_a, port_b);
135
        assert_eq!(port_b, port_a);
136
    }
137
138
    #[test]
139
    fn partialeq_u16() {
140
        let port = Port::from_str("8080").unwrap();
141
        // test equals in both directions
142
        assert_eq!(port, 8080);
143
        assert_eq!(8080, port);
144
    }
145
146
    #[test]
147
    fn u16_from_port() {
148
        let port = Port::from_str("8080").unwrap();
149
        assert_eq!(8080, u16::from(port));
150
    }
151
}