cidr/inet_pair/
combined.rs

1use core::fmt;
2use std::net::IpAddr;
3
4use crate::{
5	errors::*,
6	internal_traits::PrivInetPair,
7	num::NumberOfAddresses,
8	Family,
9	InetIterator,
10	InetPair,
11	IpCidr,
12	IpInet,
13	IpInetPair,
14	Ipv4InetPair,
15	Ipv6InetPair,
16};
17
18impl IpInetPair {
19	/// Whether representing an IPv4 network
20	pub const fn is_ipv4(&self) -> bool {
21		match self {
22			Self::V4(_) => true,
23			Self::V6(_) => false,
24		}
25	}
26
27	/// Whether representing an IPv6 network
28	pub const fn is_ipv6(&self) -> bool {
29		match self {
30			Self::V4(_) => false,
31			Self::V6(_) => true,
32		}
33	}
34
35	// --- copy of trait API
36
37	/// Create new pair from two addresses in the same network
38	///
39	/// Fails if the addresses are not in the same network.
40	pub const fn new(first: IpInet, second: IpInet) -> Result<Self, InetTupleError> {
41		match (first, second) {
42			(IpInet::V4(first), IpInet::V4(second)) => match Ipv4InetPair::new(first, second) {
43				Ok(pair) => Ok(Self::V4(pair)),
44				Err(e) => Err(e),
45			},
46			(IpInet::V6(first), IpInet::V6(second)) => match Ipv6InetPair::new(first, second) {
47				Ok(pair) => Ok(Self::V6(pair)),
48				Err(e) => Err(e),
49			},
50			_ => Err(InetTupleError::NotInSharedNetwork),
51		}
52	}
53
54	/// Create new pair from two addresses and a common length
55	///
56	/// Fails if the network length is invalid for the addresses or the addresses are not in the same network.
57	pub const fn new_from_addresses(
58		first: IpAddr,
59		second: IpAddr,
60		len: u8,
61	) -> Result<Self, InetTupleError> {
62		match (first, second) {
63			(IpAddr::V4(first), IpAddr::V4(second)) => {
64				match Ipv4InetPair::new_from_addresses(first, second, len) {
65					Ok(pair) => Ok(Self::V4(pair)),
66					Err(e) => Err(e),
67				}
68			},
69			(IpAddr::V6(first), IpAddr::V6(second)) => {
70				match Ipv6InetPair::new_from_addresses(first, second, len) {
71					Ok(pair) => Ok(Self::V6(pair)),
72					Err(e) => Err(e),
73				}
74			},
75			_ => Err(InetTupleError::NotInSharedNetwork),
76		}
77	}
78
79	/// First address
80	pub const fn first(&self) -> IpInet {
81		match self {
82			Self::V4(p) => IpInet::V4(p.first()),
83			Self::V6(p) => IpInet::V6(p.first()),
84		}
85	}
86
87	/// Second address
88	pub const fn second(&self) -> IpInet {
89		match self {
90			Self::V4(p) => IpInet::V4(p.second()),
91			Self::V6(p) => IpInet::V6(p.second()),
92		}
93	}
94
95	/// network (i.e. drops the host information)
96	pub const fn network(&self) -> IpCidr {
97		match self {
98			Self::V4(p) => IpCidr::V4(p.network()),
99			Self::V6(p) => IpCidr::V6(p.network()),
100		}
101	}
102
103	/// length in bits of the shared prefix of the contained addresses
104	pub const fn network_length(&self) -> u8 {
105		match self {
106			Self::V4(p) => p.network_length(),
107			Self::V6(p) => p.network_length(),
108		}
109	}
110
111	/// IP family of the contained address ([`Ipv4`] or [`Ipv6`]).
112	///
113	/// [`Ipv4`]: Family::Ipv4
114	/// [`Ipv6`]: Family::Ipv6
115	pub const fn family(&self) -> Family {
116		match self {
117			Self::V4(_) => Family::Ipv4,
118			Self::V6(_) => Family::Ipv6,
119		}
120	}
121
122	/// Iterate over `first..=second` (inclusive)
123	pub const fn iter(self) -> InetIterator<IpAddr> {
124		InetIterator::_new(self)
125	}
126}
127
128impl PrivInetPair for IpInetPair {
129	fn _covered_addresses(&self) -> NumberOfAddresses {
130		match self {
131			Self::V4(p) => p._covered_addresses(),
132			Self::V6(p) => p._covered_addresses(),
133		}
134	}
135
136	fn _inc_first(&mut self) -> bool {
137		match self {
138			Self::V4(p) => p._inc_first(),
139			Self::V6(p) => p._inc_first(),
140		}
141	}
142
143	fn _dec_second(&mut self) -> bool {
144		match self {
145			Self::V4(p) => p._dec_second(),
146			Self::V6(p) => p._dec_second(),
147		}
148	}
149}
150
151impl InetPair for IpInetPair {
152	type Address = IpAddr;
153
154	fn new(first: IpInet, second: IpInet) -> Result<Self, InetTupleError> {
155		match (first, second) {
156			(IpInet::V4(first), IpInet::V4(second)) => {
157				Ok(Self::V4(Ipv4InetPair::new(first, second)?))
158			},
159			(IpInet::V6(first), IpInet::V6(second)) => {
160				Ok(Self::V6(Ipv6InetPair::new(first, second)?))
161			},
162			_ => Err(InetTupleError::NotInSharedNetwork),
163		}
164	}
165
166	fn new_from_addresses(first: IpAddr, second: IpAddr, len: u8) -> Result<Self, InetTupleError> {
167		match (first, second) {
168			(IpAddr::V4(first), IpAddr::V4(second)) => Ok(Self::V4(
169				Ipv4InetPair::new_from_addresses(first, second, len)?,
170			)),
171			(IpAddr::V6(first), IpAddr::V6(second)) => Ok(Self::V6(
172				Ipv6InetPair::new_from_addresses(first, second, len)?,
173			)),
174			_ => Err(InetTupleError::NotInSharedNetwork),
175		}
176	}
177
178	fn first(&self) -> IpInet {
179		match self {
180			Self::V4(p) => IpInet::V4(p.first()),
181			Self::V6(p) => IpInet::V6(p.first()),
182		}
183	}
184
185	fn second(&self) -> IpInet {
186		match self {
187			Self::V4(p) => IpInet::V4(p.second()),
188			Self::V6(p) => IpInet::V6(p.second()),
189		}
190	}
191
192	fn network(&self) -> IpCidr {
193		match self {
194			Self::V4(p) => IpCidr::V4(p.network()),
195			Self::V6(p) => IpCidr::V6(p.network()),
196		}
197	}
198
199	fn network_length(&self) -> u8 {
200		match self {
201			Self::V4(p) => p.network_length(),
202			Self::V6(p) => p.network_length(),
203		}
204	}
205
206	fn family(&self) -> Family {
207		match self {
208			Self::V4(_) => Family::Ipv4,
209			Self::V6(_) => Family::Ipv6,
210		}
211	}
212
213	fn iter(self) -> InetIterator<IpAddr> {
214		self.iter()
215	}
216}
217
218impl fmt::Display for IpInetPair {
219	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
220		match self {
221			Self::V4(c) => fmt::Display::fmt(c, f),
222			Self::V6(c) => fmt::Display::fmt(c, f),
223		}
224	}
225}
226
227impl From<Ipv4InetPair> for IpInetPair {
228	fn from(c: Ipv4InetPair) -> Self {
229		Self::V4(c)
230	}
231}
232
233impl From<Ipv6InetPair> for IpInetPair {
234	fn from(c: Ipv6InetPair) -> Self {
235		Self::V6(c)
236	}
237}
238
239impl IntoIterator for IpInetPair {
240	type IntoIter = InetIterator<IpAddr>;
241	type Item = IpInet;
242
243	fn into_iter(self) -> Self::IntoIter {
244		self.iter()
245	}
246}