message_io/network/
remote_addr.rs1use serde::{Serialize, Deserialize};
2
3use std::net::{SocketAddr, ToSocketAddrs, IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
4use std::io::{self};
5
6#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Hash, Debug)]
13pub enum RemoteAddr {
14 Socket(SocketAddr),
15 Str(String),
16}
17
18impl RemoteAddr {
19 pub fn is_socket_addr(&self) -> bool {
21 matches!(self, RemoteAddr::Socket(_))
22 }
23
24 pub fn is_string(&self) -> bool {
26 matches!(self, RemoteAddr::Socket(_))
27 }
28
29 pub fn socket_addr(&self) -> &SocketAddr {
32 match self {
33 RemoteAddr::Socket(addr) => addr,
34 _ => panic!("The RemoteAddr must be a SocketAddr"),
35 }
36 }
37
38 pub fn string(&self) -> &str {
41 match self {
42 RemoteAddr::Str(addr) => addr,
43 _ => panic!("The RemoteAddr must be a String"),
44 }
45 }
46}
47
48impl ToSocketAddrs for RemoteAddr {
49 type Iter = std::option::IntoIter<SocketAddr>;
50 fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
51 match self {
52 RemoteAddr::Socket(addr) => addr.to_socket_addrs(),
53 RemoteAddr::Str(_) => Err(io::Error::new(
54 io::ErrorKind::InvalidInput,
55 "The RemoteAddr is not a SocketAddr",
56 )),
57 }
58 }
59}
60
61impl std::fmt::Display for RemoteAddr {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 match self {
64 RemoteAddr::Socket(addr) => write!(f, "{addr}"),
65 RemoteAddr::Str(string) => write!(f, "{string}"),
66 }
67 }
68}
69
70pub trait ToRemoteAddr {
76 fn to_remote_addr(&self) -> io::Result<RemoteAddr>;
77}
78
79impl ToRemoteAddr for &str {
80 fn to_remote_addr(&self) -> io::Result<RemoteAddr> {
81 Ok(match self.parse() {
82 Ok(addr) => RemoteAddr::Socket(addr),
83 Err(_) => RemoteAddr::Str(self.to_string()),
84 })
85 }
86}
87
88impl ToRemoteAddr for String {
89 fn to_remote_addr(&self) -> io::Result<RemoteAddr> {
90 (self as &str).to_remote_addr()
91 }
92}
93
94impl ToRemoteAddr for &String {
95 fn to_remote_addr(&self) -> io::Result<RemoteAddr> {
96 (self as &str).to_remote_addr()
97 }
98}
99
100impl ToRemoteAddr for SocketAddr {
101 fn to_remote_addr(&self) -> io::Result<RemoteAddr> {
102 Ok(RemoteAddr::Socket(*self))
103 }
104}
105
106impl ToRemoteAddr for SocketAddrV4 {
107 fn to_remote_addr(&self) -> io::Result<RemoteAddr> {
108 Ok(RemoteAddr::Socket(SocketAddr::V4(*self)))
109 }
110}
111
112impl ToRemoteAddr for SocketAddrV6 {
113 fn to_remote_addr(&self) -> io::Result<RemoteAddr> {
114 Ok(RemoteAddr::Socket(SocketAddr::V6(*self)))
115 }
116}
117
118impl ToRemoteAddr for RemoteAddr {
119 fn to_remote_addr(&self) -> io::Result<RemoteAddr> {
120 Ok(self.clone())
121 }
122}
123
124impl ToRemoteAddr for (&str, u16) {
125 fn to_remote_addr(&self) -> io::Result<RemoteAddr> {
126 Ok(RemoteAddr::Socket(self.to_socket_addrs().unwrap().next().unwrap()))
127 }
128}
129
130impl ToRemoteAddr for (String, u16) {
131 fn to_remote_addr(&self) -> io::Result<RemoteAddr> {
132 Ok(RemoteAddr::Socket(self.to_socket_addrs().unwrap().next().unwrap()))
133 }
134}
135
136impl ToRemoteAddr for (IpAddr, u16) {
137 fn to_remote_addr(&self) -> io::Result<RemoteAddr> {
138 Ok(RemoteAddr::Socket(self.to_socket_addrs().unwrap().next().unwrap()))
139 }
140}
141
142impl ToRemoteAddr for (Ipv4Addr, u16) {
143 fn to_remote_addr(&self) -> io::Result<RemoteAddr> {
144 Ok(RemoteAddr::Socket(self.to_socket_addrs().unwrap().next().unwrap()))
145 }
146}
147
148impl ToRemoteAddr for (Ipv6Addr, u16) {
149 fn to_remote_addr(&self) -> io::Result<RemoteAddr> {
150 Ok(RemoteAddr::Socket(self.to_socket_addrs().unwrap().next().unwrap()))
151 }
152}
153
154#[cfg(test)]
155mod tests {
156 use super::*;
157 use std::net::{IpAddr, Ipv4Addr};
158
159 #[test]
160 fn str_to_string() {
161 let string = "ws://domain:1234/socket";
162 assert_eq!(string, string.to_remote_addr().unwrap().string());
163 }
164
165 #[test]
166 fn string_to_string() {
167 let string = String::from("ws://domain:1234/socket");
168 assert_eq!(&string, string.to_remote_addr().unwrap().string());
169 }
170
171 #[test]
172 fn str_to_socket_addr() {
173 assert!("127.0.0.1:80".to_remote_addr().unwrap().is_socket_addr());
174 }
175
176 #[test]
177 fn string_to_socket_addr() {
178 assert!(String::from("127.0.0.1:80").to_remote_addr().unwrap().is_socket_addr());
179 }
180
181 #[test]
182 fn socket_addr_to_socket_addr() {
183 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
184 assert!(socket_addr.to_remote_addr().unwrap().is_socket_addr());
185 }
186}