cidr_utils/iterator/
v4.rs1use std::net::Ipv4Addr;
2
3use cidr::Ipv4Cidr;
4
5use crate::Ipv4CidrSize;
6
7#[derive(Debug)]
11pub struct Ipv4CidrU8ArrayIterator {
12 from: u32,
13 size: u64,
14 next: u64,
15 back: u64,
16}
17
18impl Ipv4CidrU8ArrayIterator {
19 #[inline]
20 pub fn new(cidr: &Ipv4Cidr) -> Self {
21 let from: u32 = cidr.first_address().into();
22 let size = cidr.size();
23
24 Self {
25 from,
26 size,
27 next: 0,
28 back: size,
29 }
30 }
31}
32
33impl Ipv4CidrU8ArrayIterator {
34 #[inline]
35 unsafe fn next_unchecked(&mut self) -> [u8; 4] {
36 let p = self.from + self.next as u32;
37
38 self.next += 1;
39
40 p.to_be_bytes()
41 }
42
43 #[inline]
44 unsafe fn next_back_unchecked(&mut self) -> [u8; 4] {
45 self.back -= 1;
46
47 let p = self.from + self.back as u32;
48
49 p.to_be_bytes()
50 }
51
52 #[inline]
53 pub fn nth_u64(&mut self, n: u64) -> Option<[u8; 4]> {
54 self.next += n;
55
56 if self.next < self.back {
57 Some(unsafe { self.next_unchecked() })
58 } else {
59 self.next = self.size;
60
61 None
62 }
63 }
64
65 #[inline]
66 pub fn nth_back_u64(&mut self, n: u64) -> Option<[u8; 4]> {
67 if self.back > n {
68 self.back -= n;
69
70 if self.next < self.back {
71 return Some(unsafe { self.next_back_unchecked() });
72 }
73 }
74
75 self.next = self.size;
76
77 None
78 }
79}
80
81impl Iterator for Ipv4CidrU8ArrayIterator {
82 type Item = [u8; 4];
83
84 #[inline]
85 fn next(&mut self) -> Option<Self::Item> {
86 if self.next < self.back {
87 Some(unsafe { self.next_unchecked() })
88 } else {
89 None
90 }
91 }
92
93 #[cfg(not(any(
94 target_pointer_width = "8",
95 target_pointer_width = "16",
96 target_pointer_width = "32"
97 )))]
98 #[inline]
99 fn size_hint(&self) -> (usize, Option<usize>) {
100 let remaining_ips = (self.back - self.next) as usize;
101
102 (remaining_ips, Some(remaining_ips))
103 }
104
105 #[cfg(not(any(
106 target_pointer_width = "8",
107 target_pointer_width = "16",
108 target_pointer_width = "32"
109 )))]
110 #[inline]
111 fn count(self) -> usize
112 where
113 Self: Sized, {
114 if self.next < self.back {
115 (self.back - self.next) as usize
116 } else {
117 0
118 }
119 }
120
121 #[inline]
122 fn last(mut self) -> Option<Self::Item> {
123 if self.next < self.back {
124 self.next = self.back - 1;
125
126 Some(unsafe { self.next_unchecked() })
127 } else {
128 None
129 }
130 }
131
132 #[inline]
133 fn nth(&mut self, n: usize) -> Option<Self::Item> {
134 self.nth_u64(n as u64)
135 }
136}
137
138impl DoubleEndedIterator for Ipv4CidrU8ArrayIterator {
139 #[inline]
140 fn next_back(&mut self) -> Option<Self::Item> {
141 if self.next < self.back {
142 Some(unsafe { self.next_back_unchecked() })
143 } else {
144 None
145 }
146 }
147
148 #[inline]
149 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
150 self.nth_back_u64(n as u64)
151 }
152}
153
154#[derive(Debug)]
158pub struct Ipv4CidrIterator {
159 iter: Ipv4CidrU8ArrayIterator,
160}
161
162impl Ipv4CidrIterator {
163 #[inline]
164 pub fn new(cidr: &Ipv4Cidr) -> Self {
165 Self {
166 iter: Ipv4CidrU8ArrayIterator::new(cidr)
167 }
168 }
169}
170
171impl Ipv4CidrIterator {
172 #[inline]
173 pub fn nth_u64(&mut self, n: u64) -> Option<u32> {
174 self.iter.nth_u64(n).map(u32::from_be_bytes)
175 }
176}
177
178impl Iterator for Ipv4CidrIterator {
179 type Item = u32;
180
181 #[inline]
182 fn next(&mut self) -> Option<Self::Item> {
183 self.iter.next().map(u32::from_be_bytes)
184 }
185
186 #[inline]
187 fn last(self) -> Option<Self::Item> {
188 self.iter.last().map(u32::from_be_bytes)
189 }
190
191 #[inline]
192 fn nth(&mut self, n: usize) -> Option<Self::Item> {
193 self.iter.nth(n).map(u32::from_be_bytes)
194 }
195}
196
197impl DoubleEndedIterator for Ipv4CidrIterator {
198 #[inline]
199 fn next_back(&mut self) -> Option<Self::Item> {
200 self.iter.next_back().map(u32::from_be_bytes)
201 }
202
203 #[inline]
204 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
205 self.iter.nth_back(n).map(u32::from_be_bytes)
206 }
207}
208
209#[derive(Debug)]
213pub struct Ipv4CidrIpv4AddrIterator {
214 iter: Ipv4CidrU8ArrayIterator,
215}
216
217impl Ipv4CidrIpv4AddrIterator {
218 #[inline]
219 pub fn new(cidr: &Ipv4Cidr) -> Self {
220 Self {
221 iter: Ipv4CidrU8ArrayIterator::new(cidr)
222 }
223 }
224}
225
226impl Ipv4CidrIpv4AddrIterator {
227 #[inline]
228 pub fn nth_u64(&mut self, n: u64) -> Option<Ipv4Addr> {
229 self.iter.nth_u64(n).map(|a| a.into())
230 }
231}
232
233impl Iterator for Ipv4CidrIpv4AddrIterator {
234 type Item = Ipv4Addr;
235
236 #[inline]
237 fn next(&mut self) -> Option<Self::Item> {
238 self.iter.next().map(|a| a.into())
239 }
240
241 #[inline]
242 fn last(self) -> Option<Self::Item> {
243 self.iter.last().map(|a| a.into())
244 }
245
246 #[inline]
247 fn nth(&mut self, n: usize) -> Option<Self::Item> {
248 self.iter.nth(n).map(|a| a.into())
249 }
250}
251
252impl DoubleEndedIterator for Ipv4CidrIpv4AddrIterator {
253 #[inline]
254 fn next_back(&mut self) -> Option<Self::Item> {
255 self.iter.next_back().map(|a| a.into())
256 }
257
258 #[inline]
259 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
260 self.iter.nth_back(n).map(|a| a.into())
261 }
262}