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 pub const fn is_ipv4(&self) -> bool {
21 match self {
22 Self::V4(_) => true,
23 Self::V6(_) => false,
24 }
25 }
26
27 pub const fn is_ipv6(&self) -> bool {
29 match self {
30 Self::V4(_) => false,
31 Self::V6(_) => true,
32 }
33 }
34
35 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 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 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 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 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 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 pub const fn family(&self) -> Family {
116 match self {
117 Self::V4(_) => Family::Ipv4,
118 Self::V6(_) => Family::Ipv6,
119 }
120 }
121
122 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}