1use core::fmt;
2
3use super::{ErrorKind, InvalidUri};
4
5pub struct Port<T> {
7 port: u16,
8 repr: T,
9}
10
11impl<T> Port<T> {
12 pub fn as_u16(&self) -> u16 {
26 self.port
27 }
28}
29
30impl<T> Port<T>
31where
32 T: AsRef<str>,
33{
34 pub(crate) fn from_str(bytes: T) -> Result<Self, InvalidUri> {
38 bytes
39 .as_ref()
40 .parse::<u16>()
41 .map(|port| Port { port, repr: bytes })
42 .map_err(|_| ErrorKind::InvalidPort.into())
43 }
44
45 pub fn as_str(&self) -> &str {
59 self.repr.as_ref()
60 }
61}
62
63impl<T> fmt::Debug for Port<T>
64where
65 T: fmt::Debug,
66{
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 f.debug_tuple("Port").field(&self.port).finish()
69 }
70}
71
72impl<T> fmt::Display for Port<T> {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 fmt::Display::fmt(&self.port, f)
77 }
78}
79
80impl<T> From<Port<T>> for u16 {
81 fn from(port: Port<T>) -> Self {
82 port.as_u16()
83 }
84}
85
86impl<T> AsRef<str> for Port<T>
87where
88 T: AsRef<str>,
89{
90 fn as_ref(&self) -> &str {
91 self.as_str()
92 }
93}
94
95impl<T, U> PartialEq<Port<U>> for Port<T> {
96 fn eq(&self, other: &Port<U>) -> bool {
97 self.port == other.port
98 }
99}
100
101impl<T> PartialEq<u16> for Port<T> {
102 fn eq(&self, other: &u16) -> bool {
103 self.port == *other
104 }
105}
106
107impl<T> PartialEq<Port<T>> for u16 {
108 fn eq(&self, other: &Port<T>) -> bool {
109 other.port == *self
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use alloc::string::String;
116
117 use super::*;
118
119 #[test]
120 fn partialeq_port() {
121 let port_a = Port::from_str("8080").unwrap();
122 let port_b = Port::from_str("8080").unwrap();
123 assert_eq!(port_a, port_b);
124 }
125
126 #[test]
127 fn partialeq_port_different_reprs() {
128 let port_a = Port {
129 repr: "8081",
130 port: 8081,
131 };
132 let port_b = Port {
133 repr: String::from("8081"),
134 port: 8081,
135 };
136 assert_eq!(port_a, port_b);
137 assert_eq!(port_b, port_a);
138 }
139
140 #[test]
141 fn partialeq_u16() {
142 let port = Port::from_str("8080").unwrap();
143 assert_eq!(port, 8080);
145 assert_eq!(8080, port);
146 }
147
148 #[test]
149 fn u16_from_port() {
150 let port = Port::from_str("8080").unwrap();
151 assert_eq!(8080, u16::from(port));
152 }
153}