cidr/traits.rs
1use crate::{
2 errors::{
3 InetTupleError,
4 NetworkLengthTooLongError,
5 NetworkParseError,
6 },
7 internal_traits::{
8 PrivCidr,
9 PrivInet,
10 PrivInetPair,
11 PrivUnspecAddress,
12 },
13 Family,
14 InetIterator,
15};
16use core::{
17 fmt::Debug,
18 hash::Hash,
19};
20
21/// Maps IP address type to other types based on this address type
22///
23/// Implemented for [`IPv4Addr`], [`IPv6Addr`] and [`IpAddr`].
24///
25/// [`Ipv4Addr`]: std::net::Ipv4Addr
26/// [`Ipv6Addr`]: std::net::Ipv6Addr
27/// [`IpAddr`]: std::net::IpAddr
28pub trait Address: Copy + Debug + Ord + Hash + PrivUnspecAddress {
29 /// Corresponding [`Inet`] type (representing an address + a network
30 /// containing it)
31 type Inet: Inet<Address = Self>;
32
33 /// Corresponding [`Cidr`] type (representing only a network, not a specific
34 /// address within)
35 type Cidr: Cidr<Address = Self>;
36
37 /// Corresponding [`InetPair`] type (representing two addresses in the same network)
38 type InetPair: InetPair<Address = Self>;
39}
40
41/// Types implementing [`Cidr`] represent IP networks. An IP network in
42/// this case is a set of IP addresses which share a common prefix (when
43/// viewed as a bitstring). The length of this prefix is called
44/// `network_length`.
45///
46/// In the standard representation the network is identified by the
47/// first address and the network length, separated by a '/'.
48///
49/// The parsers will expect the input in the same format, i.e. only the
50/// first address of the network is accepted.
51///
52/// The first network length bits in an address representing the network
53/// are the network part, the remaining bits are the host part.
54/// Requiring an address to be the first in a network is equivalent to
55/// requiring the host part being zero.
56pub trait Cidr: Copy + Debug + Ord + Hash + PrivCidr {
57 /// Type for the underlying address ([`IpAddr`], [`Ipv4Addr`] or
58 /// [`Ipv6Addr`]).
59 ///
60 /// [`Ipv4Addr`]: std::net::Ipv4Addr
61 /// [`Ipv6Addr`]: std::net::Ipv6Addr
62 /// [`IpAddr`]: std::net::IpAddr
63 type Address: Address<Cidr = Self>;
64
65 /// Create new network from address and prefix length. If the
66 /// network length exceeds the address length or the address is not
67 /// the first address in the network ("host part not zero") an
68 /// error is returned.
69 fn new(addr: Self::Address, len: u8) -> Result<Self, NetworkParseError>;
70
71 /// Create a network containing a single address (network length =
72 /// address length).
73 fn new_host(addr: Self::Address) -> Self;
74
75 /// Iterate over all addresses in the range. With IPv6 addresses
76 /// this can produce really long iterations (up to 2<sup>128</sup>
77 /// addresses).
78 fn iter(&self) -> InetIterator<Self::Address>;
79
80 /// first address in the network as plain address
81 fn first_address(&self) -> Self::Address;
82 /// first address in the network
83 fn first(&self) -> <Self::Address as Address>::Inet;
84 /// last address in the network as plain address
85 fn last_address(&self) -> Self::Address;
86 /// last address in the network
87 fn last(&self) -> <Self::Address as Address>::Inet;
88 /// length in bits of the shared prefix of the contained addresses
89 fn network_length(&self) -> u8;
90 /// IP family of the contained address ([`Ipv4`] or [`Ipv6`]).
91 ///
92 /// [`Ipv4`]: Family::Ipv4
93 /// [`Ipv6`]: Family::Ipv6
94 fn family(&self) -> Family;
95
96 /// whether network represents a single host address
97 fn is_host_address(&self) -> bool;
98
99 /// network mask: an pseudo address which has the first `network
100 /// length` bits set to 1 and the remaining to 0.
101 fn mask(&self) -> Self::Address;
102
103 /// check whether an address is contained in the network
104 fn contains(&self, addr: &Self::Address) -> bool;
105}
106
107/// Types implementing Inet represent IP hosts within networks.
108///
109/// In addition to the network represented by the corresponding [`Cidr`]
110/// type, an [`Inet`] type also stores a single host address which is part
111/// of the network.
112///
113/// The host address is not really stored as separate data, but is
114/// stored together with the network address.
115///
116/// The representation of a [`Inet`] type is similar to that of the
117/// corresponding [`Cidr`] type, but uses the host address instead of the
118/// first address of the network.
119pub trait Inet: Copy + Debug + Ord + Hash + PrivInet {
120 /// Type for the underlying address ([`IpAddr`], [`Ipv4Addr`] or
121 /// [`Ipv6Addr`]).
122 ///
123 /// [`Ipv4Addr`]: std::net::Ipv4Addr
124 /// [`Ipv6Addr`]: std::net::Ipv6Addr
125 /// [`IpAddr`]: std::net::IpAddr
126 type Address: Address<Inet = Self>;
127
128 /// Create new host within a network from address and prefix length.
129 /// If the network length exceeds the address length an error is
130 /// returned.
131 fn new(addr: Self::Address, len: u8) -> Result<Self, NetworkLengthTooLongError>;
132
133 /// Create a network containing a single address as host and the
134 /// network (network length = address length).
135 fn new_host(addr: Self::Address) -> Self;
136
137 /// increments host part (without changing the network part);
138 /// returns true on wrap around
139 fn increment(&mut self) -> bool;
140
141 /// Returns next address in network or `None` if it was the last address in the network
142 fn next(self) -> Option<Self>;
143
144 /// decrements host part (without changing the network part);
145 /// returns true on wrap around
146 fn decrement(&mut self) -> bool;
147
148 /// Returns previous address in network or `None` if it was the first address in the network
149 fn previous(self) -> Option<Self>;
150
151 /// Find the nth host after the current one in the current network
152 ///
153 /// Returned boolean indicates whether an overflow occured.
154 fn overflowing_add(self, step: u128) -> (Self, bool);
155
156 /// Find the nth host before the current one in the current network
157 ///
158 /// Returned boolean indicates whether an overflow occured.
159 fn overflowing_sub(self, step: u128) -> (Self, bool);
160
161 /// network (i.e. drops the host information)
162 fn network(&self) -> <Self::Address as Address>::Cidr;
163
164 /// the host
165 fn address(&self) -> Self::Address;
166
167 /// first address in the network as plain address
168 fn first_address(&self) -> Self::Address;
169 /// first address in the network
170 fn first(&self) -> Self;
171 /// last address in the network as plain address
172 fn last_address(&self) -> Self::Address;
173 /// last address in the network
174 fn last(&self) -> Self;
175 /// length in bits of the shared prefix of the contained addresses
176 fn network_length(&self) -> u8;
177 /// IP family of the contained address ([`Ipv4`] or [`Ipv6`]).
178 ///
179 /// [`Ipv4`]: Family::Ipv4
180 /// [`Ipv6`]: Family::Ipv6
181 fn family(&self) -> Family;
182
183 /// whether network represents a single host address
184 fn is_host_address(&self) -> bool;
185
186 /// network mask: an pseudo address which has the first `network
187 /// length` bits set to 1 and the remaining to 0.
188 fn mask(&self) -> Self::Address;
189
190 /// check whether an address is contained in the network
191 fn contains(&self, addr: &Self::Address) -> bool;
192}
193
194/// Pair of two addresses in the same network
195pub trait InetPair: Copy + Debug + Eq + Hash + PrivInetPair {
196 /// Type for the underlying address ([`IpAddr`], [`Ipv4Addr`] or
197 /// [`Ipv6Addr`]).
198 ///
199 /// [`Ipv4Addr`]: std::net::Ipv4Addr
200 /// [`Ipv6Addr`]: std::net::Ipv6Addr
201 /// [`IpAddr`]: std::net::IpAddr
202 type Address: Address<InetPair = Self>;
203
204 /// Create new pair from two addresses in the same network
205 ///
206 /// Fails if the addresses are not in the same network.
207 fn new(
208 first: <Self::Address as Address>::Inet,
209 second: <Self::Address as Address>::Inet,
210 ) -> Result<Self, InetTupleError>;
211
212 /// Create new pair from two addresses and a common length
213 ///
214 /// Fails if the network length is invalid for the addresses or the addresses are not in the same network.
215 fn new_from_addresses(
216 first: Self::Address,
217 second: Self::Address,
218 len: u8,
219 ) -> Result<Self, InetTupleError>;
220
221 /// First address
222 fn first(&self) -> <Self::Address as Address>::Inet;
223
224 /// Second address
225 fn second(&self) -> <Self::Address as Address>::Inet;
226
227 /// network (i.e. drops the host information)
228 fn network(&self) -> <Self::Address as Address>::Cidr;
229
230 /// length in bits of the shared prefix of the contained addresses
231 fn network_length(&self) -> u8;
232
233 /// IP family of the contained address ([`Ipv4`] or [`Ipv6`]).
234 ///
235 /// [`Ipv4`]: Family::Ipv4
236 /// [`Ipv6`]: Family::Ipv6
237 fn family(&self) -> Family;
238
239 /// Iterate over `first..=second` (inclusive)
240 fn iter(self) -> InetIterator<Self::Address>;
241}