trillium_server_common/listener_config/
into_listen_addr.rs1use std::{
2 fmt::Display,
3 io,
4 net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs},
5};
6
7pub trait IntoListenAddr {
15 fn into_listen_addr(self) -> io::Result<SocketAddr>;
18}
19
20fn resolve_first(addr: impl ToSocketAddrs, label: impl Display) -> io::Result<SocketAddr> {
23 addr.to_socket_addrs()?
24 .next()
25 .ok_or_else(|| io::Error::other(format!("`{label}` did not resolve to a bind address")))
26}
27
28impl IntoListenAddr for SocketAddr {
29 fn into_listen_addr(self) -> io::Result<SocketAddr> {
30 Ok(self)
31 }
32}
33
34impl IntoListenAddr for SocketAddrV4 {
35 fn into_listen_addr(self) -> io::Result<SocketAddr> {
36 Ok(self.into())
37 }
38}
39
40impl IntoListenAddr for SocketAddrV6 {
41 fn into_listen_addr(self) -> io::Result<SocketAddr> {
42 Ok(self.into())
43 }
44}
45
46impl IntoListenAddr for u16 {
47 fn into_listen_addr(self) -> io::Result<SocketAddr> {
48 Ok(SocketAddr::from((Ipv4Addr::UNSPECIFIED, self)))
49 }
50}
51
52impl IntoListenAddr for (IpAddr, u16) {
53 fn into_listen_addr(self) -> io::Result<SocketAddr> {
54 Ok(SocketAddr::from(self))
55 }
56}
57
58impl IntoListenAddr for (Ipv4Addr, u16) {
59 fn into_listen_addr(self) -> io::Result<SocketAddr> {
60 Ok(SocketAddr::from(self))
61 }
62}
63
64impl IntoListenAddr for (Ipv6Addr, u16) {
65 fn into_listen_addr(self) -> io::Result<SocketAddr> {
66 Ok(SocketAddr::from(self))
67 }
68}
69
70impl IntoListenAddr for &str {
71 fn into_listen_addr(self) -> io::Result<SocketAddr> {
72 resolve_first(self, self)
73 }
74}
75
76impl IntoListenAddr for String {
77 fn into_listen_addr(self) -> io::Result<SocketAddr> {
78 resolve_first(&self, &self)
79 }
80}
81
82impl IntoListenAddr for (&str, u16) {
83 fn into_listen_addr(self) -> io::Result<SocketAddr> {
84 resolve_first(self, format!("{}:{}", self.0, self.1))
85 }
86}