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