ip_family/
lib.rs

1use std::{
2    fmt::{Debug, Display},
3    hash::Hash,
4    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs},
5    str::FromStr,
6};
7
8mod sealed {
9    pub trait Sealed {}
10}
11
12pub trait AnyIpFamily
13where
14    Self: sealed::Sealed,
15    Self::Addr: IpFamilyAddr<Family = Self>,
16    Self::SocketAddr: IpFamilySocketAddr<Family = Self>,
17    IpAddr: From<Self::Addr>,
18    SocketAddr: From<Self::SocketAddr>,
19{
20    type Addr;
21    type SocketAddr;
22
23    const FAMILY: IpFamily;
24}
25
26pub trait IpFamilyAddr
27where
28    Self: sealed::Sealed
29        + Copy
30        + Debug
31        + Display
32        + Eq
33        + From<Self::Raw>
34        + From<Self::Bytes>
35        + FromStr
36        + Hash
37        + Ord,
38    Self::Family: AnyIpFamily<Addr = Self>,
39    Self::Raw: From<Self>,
40    IpAddr: From<Self>,
41    SocketAddr: From<<Self::Family as AnyIpFamily>::SocketAddr>,
42{
43    type Family;
44    type Raw;
45    type Bytes;
46
47    const BYTES: usize;
48    const LOCALHOST: Self;
49    const UNSPECIFIED: Self;
50
51    fn octets(&self) -> Self::Bytes;
52    fn is_unspecified(&self) -> bool;
53    fn is_loopback(&self) -> bool;
54    fn is_multicast(&self) -> bool;
55}
56
57pub trait IpFamilySocketAddr
58where
59    Self: sealed::Sealed + Copy + Debug + Display + Eq + FromStr + Hash + Ord + ToSocketAddrs,
60
61    Self::Family: AnyIpFamily<SocketAddr = Self>,
62    IpAddr: From<<Self::Family as AnyIpFamily>::Addr>,
63    SocketAddr: From<Self>,
64{
65    type Family;
66
67    fn new(ip: <Self::Family as AnyIpFamily>::Addr, port: u16) -> Self;
68    fn ip(&self) -> <Self::Family as AnyIpFamily>::Addr;
69    fn set_ip(&mut self, new_ip: <Self::Family as AnyIpFamily>::Addr);
70    fn port(&self) -> u16;
71    fn set_port(&mut self, new_port: u16);
72}
73
74pub struct IpFamilyV4;
75
76impl sealed::Sealed for IpFamilyV4 {}
77impl AnyIpFamily for IpFamilyV4 {
78    type Addr = Ipv4Addr;
79
80    type SocketAddr = SocketAddrV4;
81
82    const FAMILY: IpFamily = IpFamily::V4;
83}
84
85const IPV4_ADDR_BYTES: usize = 4;
86impl sealed::Sealed for Ipv4Addr {}
87impl IpFamilyAddr for Ipv4Addr {
88    type Family = IpFamilyV4;
89    type Raw = u32;
90    type Bytes = [u8; IPV4_ADDR_BYTES];
91
92    const BYTES: usize = IPV4_ADDR_BYTES;
93    const LOCALHOST: Self = Self::LOCALHOST;
94    const UNSPECIFIED: Self = Self::UNSPECIFIED;
95
96    fn octets(&self) -> Self::Bytes {
97        self.octets()
98    }
99
100    fn is_unspecified(&self) -> bool {
101        self.is_unspecified()
102    }
103
104    fn is_loopback(&self) -> bool {
105        self.is_loopback()
106    }
107
108    fn is_multicast(&self) -> bool {
109        self.is_multicast()
110    }
111}
112
113impl sealed::Sealed for SocketAddrV4 {}
114impl IpFamilySocketAddr for SocketAddrV4 {
115    type Family = IpFamilyV4;
116
117    fn new(ip: <Self::Family as AnyIpFamily>::Addr, port: u16) -> Self {
118        Self::new(ip, port)
119    }
120
121    fn ip(&self) -> <Self::Family as AnyIpFamily>::Addr {
122        *self.ip()
123    }
124
125    fn set_ip(&mut self, new_ip: <Self::Family as AnyIpFamily>::Addr) {
126        self.set_ip(new_ip)
127    }
128
129    fn port(&self) -> u16 {
130        self.port()
131    }
132
133    fn set_port(&mut self, new_port: u16) {
134        self.set_port(new_port)
135    }
136}
137
138pub struct IpFamilyV6;
139
140impl sealed::Sealed for IpFamilyV6 {}
141impl AnyIpFamily for IpFamilyV6 {
142    type Addr = Ipv6Addr;
143
144    type SocketAddr = SocketAddrV6;
145
146    const FAMILY: IpFamily = IpFamily::V6;
147}
148
149const IPV6_ADDR_BYTES: usize = 16;
150impl sealed::Sealed for Ipv6Addr {}
151impl IpFamilyAddr for Ipv6Addr {
152    type Family = IpFamilyV6;
153    type Raw = u128;
154    type Bytes = [u8; IPV6_ADDR_BYTES];
155
156    const BYTES: usize = IPV6_ADDR_BYTES;
157    const LOCALHOST: Self = Self::LOCALHOST;
158    const UNSPECIFIED: Self = Self::UNSPECIFIED;
159
160    fn octets(&self) -> Self::Bytes {
161        self.octets()
162    }
163
164    fn is_unspecified(&self) -> bool {
165        self.is_unspecified()
166    }
167
168    fn is_loopback(&self) -> bool {
169        self.is_loopback()
170    }
171
172    fn is_multicast(&self) -> bool {
173        self.is_multicast()
174    }
175}
176
177impl sealed::Sealed for SocketAddrV6 {}
178impl IpFamilySocketAddr for SocketAddrV6 {
179    type Family = IpFamilyV6;
180
181    fn new(ip: <Self::Family as AnyIpFamily>::Addr, port: u16) -> Self {
182        Self::new(ip, port, 0, 0)
183    }
184
185    fn ip(&self) -> <Self::Family as AnyIpFamily>::Addr {
186        *self.ip()
187    }
188
189    fn set_ip(&mut self, new_ip: <Self::Family as AnyIpFamily>::Addr) {
190        self.set_ip(new_ip)
191    }
192
193    fn port(&self) -> u16 {
194        self.port()
195    }
196
197    fn set_port(&mut self, new_port: u16) {
198        self.set_port(new_port)
199    }
200}
201
202#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
203pub enum IpFamily {
204    V4,
205    V6,
206}
207
208impl IpFamily {
209    pub const fn localhost(&self) -> IpAddr {
210        match self {
211            Self::V4 => IpAddr::V4(Ipv4Addr::LOCALHOST),
212            Self::V6 => IpAddr::V6(Ipv6Addr::LOCALHOST),
213        }
214    }
215
216    pub const fn unspecified(&self) -> IpAddr {
217        match self {
218            Self::V4 => IpAddr::V4(Ipv4Addr::UNSPECIFIED),
219            Self::V6 => IpAddr::V6(Ipv6Addr::UNSPECIFIED),
220        }
221    }
222}
223
224impl AsRef<IpFamily> for IpAddr {
225    fn as_ref(&self) -> &IpFamily {
226        match self {
227            IpAddr::V4(_) => &IpFamily::V4,
228            IpAddr::V6(_) => &IpFamily::V6,
229        }
230    }
231}
232
233impl AsRef<IpFamily> for SocketAddr {
234    fn as_ref(&self) -> &IpFamily {
235        match self {
236            SocketAddr::V4(_) => &IpFamily::V4,
237            SocketAddr::V6(_) => &IpFamily::V6,
238        }
239    }
240}
241
242impl<T: AsRef<IpFamily>> From<T> for IpFamily {
243    fn from(value: T) -> Self {
244        *value.as_ref()
245    }
246}
247
248pub trait IpFamilyExt {
249    fn family(&self) -> IpFamily;
250}
251
252impl<T: AsRef<IpFamily>> IpFamilyExt for T {
253    fn family(&self) -> IpFamily {
254        *self.as_ref()
255    }
256}