prefix_trie/joint/map/iter.rs
1//! Module that contains the implementation for the iterators
2
3use crate::joint::JointPrefix;
4
5use super::JointPrefixMap;
6
7/// An iterator over all entries of a [`JointPrefixMap`] in lexicographic order.
8pub struct Iter<'a, P: JointPrefix, T> {
9 pub(crate) i1: Option<crate::map::Iter<'a, P::P1, T>>,
10 pub(crate) i2: Option<crate::map::Iter<'a, P::P2, T>>,
11}
12
13impl<P: JointPrefix, T> Default for Iter<'_, P, T> {
14 /// The default iterator is empty.
15 ///
16 /// ```
17 /// use prefix_trie::joint;
18 /// # #[cfg(feature = "ipnet")]
19 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
20 /// assert_eq!(joint::map::Iter::<ipnet::IpNet, usize>::default().count(), 0);
21 /// # Ok(())
22 /// # }
23 /// # #[cfg(not(feature = "ipnet"))]
24 /// # fn main() {}
25 /// ```
26 fn default() -> Self {
27 Self { i1: None, i2: None }
28 }
29}
30
31impl<P: JointPrefix, T> Clone for Iter<'_, P, T> {
32 /// You can clone an iterator, which maintains its state.
33 ///
34 /// ```
35 /// # use prefix_trie::joint::*;
36 /// # #[cfg(feature = "ipnet")]
37 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
38 /// let mut pm: JointPrefixMap<ipnet::IpNet, _> = JointPrefixMap::new();
39 /// pm.insert("2001::1:0:0/96".parse()?, 1);
40 /// pm.insert("192.168.0.0/22".parse()?, 2);
41 /// pm.insert("192.168.0.0/23".parse()?, 3);
42 /// let mut iter = pm.iter();
43 ///
44 /// assert_eq!(iter.next(), Some(("192.168.0.0/22".parse()?, &2)));
45 ///
46 /// let clone = iter.clone();
47 /// assert_eq!(
48 /// iter.collect::<Vec<_>>(),
49 /// vec![
50 /// ("192.168.0.0/23".parse()?, &3),
51 /// ("2001::1:0:0/96".parse()?, &1),
52 /// ]
53 /// );
54 /// assert_eq!(
55 /// clone.collect::<Vec<_>>(),
56 /// vec![
57 /// ("192.168.0.0/23".parse()?, &3),
58 /// ("2001::1:0:0/96".parse()?, &1),
59 /// ]
60 /// );
61 /// # Ok(())
62 /// # }
63 /// # #[cfg(not(feature = "ipnet"))]
64 /// # fn main() {}
65 /// ```
66 fn clone(&self) -> Self {
67 Self {
68 i1: self.i1.clone(),
69 i2: self.i2.clone(),
70 }
71 }
72}
73
74impl<'a, P: JointPrefix, T> Iterator for Iter<'a, P, T> {
75 type Item = (P, &'a T);
76
77 fn next(&mut self) -> Option<(P, &'a T)> {
78 if let Some(i1) = self.i1.as_mut() {
79 if let Some((p, t)) = i1.next() {
80 return Some((P::from_p1(p), t));
81 }
82 // iterator 1 is empty
83 self.i1 = None;
84 }
85 if let Some(i2) = self.i2.as_mut() {
86 if let Some((p, t)) = i2.next() {
87 return Some((P::from_p2(p), t));
88 }
89 // iterator 1 is empty
90 self.i2 = None;
91 }
92 None
93 }
94}
95
96/// An iterator over all prefixes of a [`JointPrefixMap`] in lexicographic order.
97#[derive(Clone, Default)]
98pub struct Keys<'a, P: JointPrefix, T> {
99 pub(crate) inner: Iter<'a, P, T>,
100}
101
102impl<P: JointPrefix, T> Iterator for Keys<'_, P, T> {
103 type Item = P;
104
105 fn next(&mut self) -> Option<P> {
106 self.inner.next().map(|(k, _)| k)
107 }
108}
109
110/// An iterator over all values of a [`JointPrefixMap`] in lexicographic order of their associated
111/// prefixes.
112#[derive(Clone, Default)]
113pub struct Values<'a, P: JointPrefix, T> {
114 pub(crate) inner: Iter<'a, P, T>,
115}
116
117impl<'a, P: JointPrefix, T> Iterator for Values<'a, P, T> {
118 type Item = &'a T;
119
120 fn next(&mut self) -> Option<&'a T> {
121 self.inner.next().map(|(_, v)| v)
122 }
123}
124
125/// An iterator over all owned entries of a [`JointPrefixMap`] in lexicographic order.
126#[derive(Clone)]
127pub struct IntoIter<P: JointPrefix, T> {
128 pub(crate) i1: Option<crate::map::IntoIter<P::P1, T>>,
129 pub(crate) i2: Option<crate::map::IntoIter<P::P2, T>>,
130}
131
132impl<P: JointPrefix, T> Iterator for IntoIter<P, T> {
133 type Item = (P, T);
134
135 fn next(&mut self) -> Option<(P, T)> {
136 if let Some(i1) = self.i1.as_mut() {
137 if let Some((p, t)) = i1.next() {
138 return Some((P::from_p1(&p), t));
139 }
140 // iterator 1 is empty
141 self.i1 = None;
142 }
143 if let Some(i2) = self.i2.as_mut() {
144 if let Some((p, t)) = i2.next() {
145 return Some((P::from_p2(&p), t));
146 }
147 // iterator 1 is empty
148 self.i2 = None;
149 }
150 None
151 }
152}
153
154/// An iterator over all prefixes of a [`JointPrefixMap`] in lexicographic order.
155#[derive(Clone)]
156pub struct IntoKeys<P: JointPrefix, T> {
157 pub(crate) inner: IntoIter<P, T>,
158}
159
160impl<P: JointPrefix, T> Iterator for IntoKeys<P, T> {
161 type Item = P;
162
163 fn next(&mut self) -> Option<P> {
164 self.inner.next().map(|(k, _)| k)
165 }
166}
167
168/// An iterator over all values of a [`JointPrefixMap`] in lexicographic order of their associated
169/// prefix.
170#[derive(Clone)]
171pub struct IntoValues<P: JointPrefix, T> {
172 pub(crate) inner: IntoIter<P, T>,
173}
174
175impl<P: JointPrefix, T> Iterator for IntoValues<P, T> {
176 type Item = T;
177
178 fn next(&mut self) -> Option<T> {
179 self.inner.next().map(|(_, v)| v)
180 }
181}
182
183impl<P: JointPrefix, T> IntoIterator for JointPrefixMap<P, T> {
184 type Item = (P, T);
185
186 type IntoIter = IntoIter<P, T>;
187
188 fn into_iter(self) -> Self::IntoIter {
189 IntoIter {
190 i1: Some(self.t1.into_iter()),
191 i2: Some(self.t2.into_iter()),
192 }
193 }
194}
195
196impl<'a, P: JointPrefix, T> IntoIterator for &'a JointPrefixMap<P, T> {
197 type Item = (P, &'a T);
198
199 type IntoIter = Iter<'a, P, T>;
200
201 fn into_iter(self) -> Self::IntoIter {
202 Iter {
203 i1: Some(self.t1.iter()),
204 i2: Some(self.t2.iter()),
205 }
206 }
207}
208
209/// A mutable iterator over a [`JointPrefixMap`]. This iterator yields elements in lexicographic order of
210/// their associated prefix.
211pub struct IterMut<'a, P: JointPrefix, T> {
212 pub(super) i1: Option<crate::map::IterMut<'a, P::P1, T>>,
213 pub(super) i2: Option<crate::map::IterMut<'a, P::P2, T>>,
214}
215
216impl<P: JointPrefix, T> Default for IterMut<'_, P, T> {
217 /// The default iterator is empty.
218 ///
219 /// ```
220 /// use prefix_trie::joint;
221 /// # #[cfg(feature = "ipnet")]
222 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
223 /// assert_eq!(joint::map::IterMut::<ipnet::IpNet, usize>::default().count(), 0);
224 /// # Ok(())
225 /// # }
226 /// # #[cfg(not(feature = "ipnet"))]
227 /// # fn main() {}
228 /// ```
229 fn default() -> Self {
230 Self { i1: None, i2: None }
231 }
232}
233
234impl<'a, P: JointPrefix, T> Iterator for IterMut<'a, P, T> {
235 type Item = (P, &'a mut T);
236
237 fn next(&mut self) -> Option<Self::Item> {
238 if let Some(i1) = self.i1.as_mut() {
239 if let Some((p, t)) = i1.next() {
240 return Some((P::from_p1(p), t));
241 }
242 // iterator 1 is empty
243 self.i1 = None;
244 }
245 if let Some(i2) = self.i2.as_mut() {
246 if let Some((p, t)) = i2.next() {
247 return Some((P::from_p2(p), t));
248 }
249 // iterator 1 is empty
250 self.i2 = None;
251 }
252 None
253 }
254}
255
256/// A mutable iterator over values of [`JointPrefixMap`]. This iterator yields elements in
257/// lexicographic order.
258#[derive(Default)]
259pub struct ValuesMut<'a, P: JointPrefix, T> {
260 // # Safety
261 // You must ensure that there only ever exists one such iterator for each tree. You may create
262 // multiple such iterators for the same tree if you start with distinct starting nodes! This
263 // ensures that any one iteration will never yield elements of the other iterator.
264 pub(crate) inner: IterMut<'a, P, T>,
265}
266
267impl<'a, P: JointPrefix, T> Iterator for ValuesMut<'a, P, T> {
268 type Item = &'a mut T;
269
270 fn next(&mut self) -> Option<Self::Item> {
271 self.inner.next().map(|(_, v)| v)
272 }
273}
274
275impl<P: JointPrefix, T> FromIterator<(P, T)> for JointPrefixMap<P, T> {
276 fn from_iter<I: IntoIterator<Item = (P, T)>>(iter: I) -> Self {
277 let mut map = Self::new();
278 iter.into_iter().for_each(|(p, v)| {
279 map.insert(p, v);
280 });
281 map
282 }
283}
284
285/// An iterator that yields all items in a `JointPrefixMap` that covers a given prefix (including
286/// the prefix itself if preseint). See [`crate::joint::JointPrefixMap::cover`] for how to create
287/// this iterator.
288pub enum Cover<'a, 'p, P: JointPrefix, T> {
289 /// Cover of the first prefix variant
290 P1(crate::map::Cover<'a, 'p, P::P1, T>),
291 /// Cover of the second prefix variant
292 P2(crate::map::Cover<'a, 'p, P::P2, T>),
293}
294
295impl<'a, P: JointPrefix, T> Iterator for Cover<'a, '_, P, T> {
296 type Item = (P, &'a T);
297
298 fn next(&mut self) -> Option<Self::Item> {
299 match self {
300 Cover::P1(cover) => cover.next().map(|(p, t)| (P::from_p1(p), t)),
301 Cover::P2(cover) => cover.next().map(|(p, t)| (P::from_p2(p), t)),
302 }
303 }
304}
305
306/// An iterator that yields all keys (prefixes) in a `JointPrefixMap` that covers a given prefix
307/// (including the prefix itself if preseint). See [`crate::joint::JointPrefixMap::cover_keys`] for
308/// how to create this iterator.
309pub struct CoverKeys<'a, 'p, P: JointPrefix, T>(pub(crate) Cover<'a, 'p, P, T>);
310
311impl<P: JointPrefix, T> Iterator for CoverKeys<'_, '_, P, T> {
312 type Item = P;
313
314 fn next(&mut self) -> Option<Self::Item> {
315 self.0.next().map(|(p, _)| p)
316 }
317}
318
319/// An iterator that yields all values in a `JointPrefixMap` that covers a given prefix (including
320/// the prefix itself if preseint). See [`crate::joint::JointPrefixMap::cover_values`] for how to
321/// create this iterator.
322pub struct CoverValues<'a, 'p, P: JointPrefix, T>(pub(super) Cover<'a, 'p, P, T>);
323
324impl<'a, P: JointPrefix, T> Iterator for CoverValues<'a, '_, P, T> {
325 type Item = &'a T;
326
327 fn next(&mut self) -> Option<Self::Item> {
328 self.0.next().map(|(_, t)| t)
329 }
330}
331
332/// An iterator over the union of two [`JointPrefixMap`]s. The iterator yields first prefixes of
333/// `P1`, followed by those of `P2`.
334pub struct Union<'a, P: JointPrefix, L, R> {
335 pub(crate) i1: Option<crate::trieview::Union<'a, P::P1, L, R>>,
336 pub(crate) i2: Option<crate::trieview::Union<'a, P::P2, L, R>>,
337}
338
339impl<'a, P: JointPrefix, L, R> Iterator for Union<'a, P, L, R> {
340 type Item = UnionItem<'a, P, L, R>;
341
342 fn next(&mut self) -> Option<Self::Item> {
343 if let Some(i1) = self.i1.as_mut() {
344 if let Some(next) = i1.next() {
345 return Some(UnionItem::from_p1(next));
346 }
347 self.i1 = None;
348 }
349 if let Some(i2) = self.i2.as_mut() {
350 if let Some(next) = i2.next() {
351 return Some(UnionItem::from_p2(next));
352 }
353 self.i2 = None;
354 }
355 None
356 }
357}
358
359/// An item of the [`Union`] iterator (over a [`JointPrefixMap`]).
360#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
361
362pub enum UnionItem<'a, P, L, R> {
363 /// The prefix is only present in the left TrieView (`self`).
364 Left {
365 /// The prefix of the element.
366 prefix: P,
367 /// The value of the element in the left TrieView (`self`).
368 left: &'a L,
369 /// The longest prefix match in the right TrieView (`other`).
370 right: Option<(P, &'a R)>,
371 },
372
373 /// The prefix is only present in the right TrieView (`other`).
374 Right {
375 /// The prefix of the element.
376 prefix: P,
377 /// The longest prefix match in the left TrieView (`self`).
378 left: Option<(P, &'a L)>,
379 /// The value of the element in the right TrieView (`other`).
380 right: &'a R,
381 },
382
383 /// The prefix is only present in the right TrieView (`other`).
384 Both {
385 /// The prefix of the element.
386 prefix: P,
387 /// The value of the element in the left TrieView (`self`).
388 left: &'a L,
389 /// The value of the element in the right TrieView (`other`).
390 right: &'a R,
391 },
392}
393
394impl<'a, P, L, R> UnionItem<'a, P, L, R> {
395 /// Get the prefix of the current element (in the exact match).
396 ///
397 /// ```
398 /// # use prefix_trie::joint::*;
399 /// # use prefix_trie::joint::map::UnionItem;
400 /// # #[cfg(feature = "ipnet")]
401 /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::IpNet>().unwrap()}; }
402 ///
403 /// # #[cfg(feature = "ipnet")]
404 /// # {
405 /// let mut map_a: JointPrefixMap<ipnet::IpNet, usize> = JointPrefixMap::from_iter([
406 /// (net!("2001::1:0:0/96"), 1),
407 /// (net!("192.168.0.0/22"), 2),
408 /// (net!("192.168.0.0/24"), 3),
409 /// ]);
410 /// let mut map_b: JointPrefixMap<ipnet::IpNet, &'static str> = JointPrefixMap::from_iter([
411 /// (net!("192.168.0.0/22"), "a"),
412 /// (net!("192.168.0.0/23"), "b"),
413 /// ]);
414 /// assert_eq!(
415 /// map_a.union(&map_b).map(|x| *x.prefix()).collect::<Vec<_>>(),
416 /// vec![
417 /// net!("192.168.0.0/22"),
418 /// net!("192.168.0.0/23"),
419 /// net!("192.168.0.0/24"),
420 /// net!("2001::1:0:0/96"),
421 /// ]
422 /// );
423 /// # }
424 /// ```
425 pub fn prefix(&self) -> &P {
426 match self {
427 UnionItem::Left { prefix, .. }
428 | UnionItem::Right { prefix, .. }
429 | UnionItem::Both { prefix, .. } => prefix,
430 }
431 }
432
433 /// Get the prefix of the current element (in the exact match).
434 ///
435 /// ```
436 /// # use prefix_trie::joint::*;
437 /// # use prefix_trie::joint::map::UnionItem;
438 /// # #[cfg(feature = "ipnet")]
439 /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::IpNet>().unwrap()}; }
440 ///
441 /// # #[cfg(feature = "ipnet")]
442 /// # {
443 /// let mut map_a: JointPrefixMap<ipnet::IpNet, usize> = JointPrefixMap::from_iter([
444 /// (net!("2001::1:0:0/96"), 1),
445 /// (net!("192.168.0.0/22"), 2),
446 /// (net!("192.168.0.0/24"), 3),
447 /// ]);
448 /// let mut map_b: JointPrefixMap<ipnet::IpNet, &'static str> = JointPrefixMap::from_iter([
449 /// (net!("192.168.0.0/22"), "a"),
450 /// (net!("192.168.0.0/23"), "b"),
451 /// ]);
452 /// assert_eq!(
453 /// map_a.union(&map_b).map(|x| x.into_prefix()).collect::<Vec<_>>(),
454 /// vec![
455 /// net!("192.168.0.0/22"),
456 /// net!("192.168.0.0/23"),
457 /// net!("192.168.0.0/24"),
458 /// net!("2001::1:0:0/96"),
459 /// ]
460 /// );
461 /// # }
462 /// ```
463 pub fn into_prefix(self) -> P {
464 match self {
465 UnionItem::Left { prefix, .. }
466 | UnionItem::Right { prefix, .. }
467 | UnionItem::Both { prefix, .. } => prefix,
468 }
469 }
470
471 /// Get the element in both the left and right map, but only if they are both present. By
472 /// doing `a.union(b).filter_map(|x| x.both)`, you get an iterator that yields only elements
473 /// that are present in both tries.
474 ///
475 /// ```
476 /// # use prefix_trie::joint::*;
477 /// # use prefix_trie::joint::map::UnionItem;
478 /// # #[cfg(feature = "ipnet")]
479 /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::IpNet>().unwrap()}; }
480 ///
481 /// # #[cfg(feature = "ipnet")]
482 /// # {
483 /// let mut map_a: JointPrefixMap<ipnet::IpNet, usize> = JointPrefixMap::from_iter([
484 /// (net!("2001::1:0:0/96"), 1),
485 /// (net!("192.168.0.0/22"), 2),
486 /// (net!("192.168.0.0/24"), 3),
487 /// ]);
488 /// let mut map_b: JointPrefixMap<ipnet::IpNet, &'static str> = JointPrefixMap::from_iter([
489 /// (net!("192.168.0.0/22"), "a"),
490 /// (net!("192.168.0.0/23"), "b"),
491 /// ]);
492 /// assert_eq!(
493 /// map_a
494 /// .union(&map_b)
495 /// .filter_map(|x| x.both().map(|(p, l, r)| (*p, l, r)))
496 /// .collect::<Vec<_>>(),
497 /// vec![(net!("192.168.0.0/22"), &2, &"a")]
498 /// );
499 /// # }
500 /// ```
501 pub fn both(&self) -> Option<(&P, &'a L, &'a R)> {
502 match self {
503 UnionItem::Left { .. } | UnionItem::Right { .. } => None,
504 UnionItem::Both {
505 prefix,
506 left,
507 right,
508 } => Some((prefix, left, right)),
509 }
510 }
511
512 /// Get the element in both the left and right map, but only if they are both present. By
513 /// doing `a.union(b).filter_map(|x| x.both)`, you get an iterator that yields only elements
514 /// that are present in both tries.
515 ///
516 /// ```
517 /// # use prefix_trie::joint::*;
518 /// # use prefix_trie::joint::map::UnionItem;
519 /// # #[cfg(feature = "ipnet")]
520 /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::IpNet>().unwrap()}; }
521 ///
522 /// # #[cfg(feature = "ipnet")]
523 /// # {
524 /// let mut map_a: JointPrefixMap<ipnet::IpNet, usize> = JointPrefixMap::from_iter([
525 /// (net!("2001::1:0:0/96"), 1),
526 /// (net!("192.168.0.0/22"), 2),
527 /// (net!("192.168.0.0/24"), 3),
528 /// ]);
529 /// let mut map_b: JointPrefixMap<ipnet::IpNet, &'static str> = JointPrefixMap::from_iter([
530 /// (net!("192.168.0.0/22"), "a"),
531 /// (net!("192.168.0.0/23"), "b"),
532 /// ]);
533 /// assert_eq!(
534 /// map_a.union(&map_b).filter_map(|x| x.into_both()).collect::<Vec<_>>(),
535 /// vec![(net!("192.168.0.0/22"), &2, &"a")]
536 /// );
537 /// # }
538 /// ```
539 pub fn into_both(self) -> Option<(P, &'a L, &'a R)> {
540 match self {
541 UnionItem::Left { .. } | UnionItem::Right { .. } => None,
542 UnionItem::Both {
543 prefix,
544 left,
545 right,
546 } => Some((prefix, left, right)),
547 }
548 }
549
550 /// Get the value of the left item (`self`). This either returns the exact match or the
551 /// longest-prefix match.
552 ///
553 /// ```
554 /// # use prefix_trie::joint::*;
555 /// # use prefix_trie::joint::map::UnionItem;
556 /// # #[cfg(feature = "ipnet")]
557 /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::IpNet>().unwrap()}; }
558 ///
559 /// # #[cfg(feature = "ipnet")]
560 /// # {
561 /// let mut map_a: JointPrefixMap<ipnet::IpNet, usize> = JointPrefixMap::from_iter([
562 /// (net!("2001::1:0:0/96"), 1),
563 /// (net!("192.168.0.0/22"), 2),
564 /// (net!("192.168.0.0/24"), 3),
565 /// ]);
566 /// let mut map_b: JointPrefixMap<ipnet::IpNet, &'static str> = JointPrefixMap::from_iter([
567 /// (net!("192.168.0.0/22"), "a"),
568 /// (net!("192.168.0.0/23"), "b"),
569 /// ]);
570 /// assert_eq!(
571 /// map_a
572 /// .union(&map_b)
573 /// .map(|x| x.left().map(|(p, l)| (*p, l)))
574 /// .collect::<Vec<_>>(),
575 /// vec![
576 /// Some((net!("192.168.0.0/22"), &2)),
577 /// Some((net!("192.168.0.0/22"), &2)),
578 /// Some((net!("192.168.0.0/24"), &3)),
579 /// Some((net!("2001::1:0:0/96"), &1)),
580 /// ]
581 /// );
582 /// # }
583 /// ```
584 pub fn left(&self) -> Option<(&P, &'a L)> {
585 match self {
586 UnionItem::Right { left, .. } => left.as_ref().map(|(p, l)| (p, *l)),
587 UnionItem::Left { prefix, left, .. } | UnionItem::Both { prefix, left, .. } => {
588 Some((prefix, left))
589 }
590 }
591 }
592
593 /// Get the value of the left item (`self`). This either returns the exact match or the
594 /// longest-prefix match.
595 ///
596 /// ```
597 /// # use prefix_trie::joint::*;
598 /// # use prefix_trie::joint::map::UnionItem;
599 /// # #[cfg(feature = "ipnet")]
600 /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::IpNet>().unwrap()}; }
601 ///
602 /// # #[cfg(feature = "ipnet")]
603 /// # {
604 /// let mut map_a: JointPrefixMap<ipnet::IpNet, usize> = JointPrefixMap::from_iter([
605 /// (net!("2001::1:0:0/96"), 1),
606 /// (net!("2001::2:0:0/96"), 2),
607 /// (net!("2001::2:0:0/98"), 3),
608 /// ]);
609 /// let mut map_b: JointPrefixMap<ipnet::IpNet, &'static str> = JointPrefixMap::from_iter([
610 /// (net!("2001::2:0:0/96"), "a"),
611 /// (net!("2001::2:0:0/97"), "b"),
612 /// ]);
613 /// assert_eq!(
614 /// map_a.union(&map_b).map(|x| x.into_left()).collect::<Vec<_>>(),
615 /// vec![
616 /// Some((net!("2001::1:0:0/96"), &1)),
617 /// Some((net!("2001::2:0:0/96"), &2)),
618 /// Some((net!("2001::2:0:0/96"), &2)),
619 /// Some((net!("2001::2:0:0/98"), &3)),
620 /// ]
621 /// );
622 /// # }
623 /// ```
624 pub fn into_left(self) -> Option<(P, &'a L)> {
625 match self {
626 UnionItem::Right { left, .. } => left,
627 UnionItem::Left { prefix, left, .. } | UnionItem::Both { prefix, left, .. } => {
628 Some((prefix, left))
629 }
630 }
631 }
632
633 /// Get the value of the right item (`other`). This either returns the exact match or the
634 /// longest-prefix match.
635 ///
636 /// ```
637 /// # use prefix_trie::joint::*;
638 /// # use prefix_trie::joint::map::UnionItem;
639 /// # #[cfg(feature = "ipnet")]
640 /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::IpNet>().unwrap()}; }
641 ///
642 /// # #[cfg(feature = "ipnet")]
643 /// # {
644 /// let mut map_a: JointPrefixMap<ipnet::IpNet, usize> = JointPrefixMap::from_iter([
645 /// (net!("2001::1:0:0/96"), 1),
646 /// (net!("192.168.0.0/22"), 2),
647 /// (net!("192.168.0.0/24"), 3),
648 /// ]);
649 /// let mut map_b: JointPrefixMap<ipnet::IpNet, &'static str> = JointPrefixMap::from_iter([
650 /// (net!("192.168.0.0/22"), "a"),
651 /// (net!("192.168.0.0/23"), "b"),
652 /// ]);
653 /// assert_eq!(
654 /// map_a
655 /// .union(&map_b)
656 /// .map(|x| x.right().map(|(p, r)| (*p, r)))
657 /// .collect::<Vec<_>>(),
658 /// vec![
659 /// Some((net!("192.168.0.0/22"), &"a")),
660 /// Some((net!("192.168.0.0/23"), &"b")),
661 /// Some((net!("192.168.0.0/23"), &"b")),
662 /// None,
663 /// ]
664 /// );
665 /// # }
666 /// ```
667 pub fn right(&self) -> Option<(&P, &'a R)> {
668 match self {
669 UnionItem::Left { right, .. } => right.as_ref().map(|(p, r)| (p, *r)),
670 UnionItem::Right { prefix, right, .. } | UnionItem::Both { prefix, right, .. } => {
671 Some((prefix, right))
672 }
673 }
674 }
675
676 /// Get the value of the right item (`other`). This either returns the exact match or the
677 /// longest-prefix match.
678 ///
679 /// ```
680 /// # use prefix_trie::joint::*;
681 /// # use prefix_trie::joint::map::UnionItem;
682 /// # #[cfg(feature = "ipnet")]
683 /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::IpNet>().unwrap()}; }
684 ///
685 /// # #[cfg(feature = "ipnet")]
686 /// # {
687 /// let mut map_a: JointPrefixMap<ipnet::IpNet, usize> = JointPrefixMap::from_iter([
688 /// (net!("2001::1:0:0/96"), 1),
689 /// (net!("2001::2:0:0/96"), 2),
690 /// (net!("2001::2:0:0/98"), 3),
691 /// ]);
692 /// let mut map_b: JointPrefixMap<ipnet::IpNet, &'static str> = JointPrefixMap::from_iter([
693 /// (net!("2001::2:0:0/96"), "a"),
694 /// (net!("2001::2:0:0/97"), "b"),
695 /// ]);
696 /// assert_eq!(
697 /// map_a.union(&map_b).map(|x| x.into_right()).collect::<Vec<_>>(),
698 /// vec![
699 /// None,
700 /// Some((net!("2001::2:0:0/96"), &"a")),
701 /// Some((net!("2001::2:0:0/97"), &"b")),
702 /// Some((net!("2001::2:0:0/97"), &"b")),
703 /// ]
704 /// );
705 /// # }
706 /// ```
707 pub fn into_right(self) -> Option<(P, &'a R)> {
708 match self {
709 UnionItem::Left { right, .. } => right,
710 UnionItem::Right { prefix, right, .. } | UnionItem::Both { prefix, right, .. } => {
711 Some((prefix, right))
712 }
713 }
714 }
715}
716
717impl<'a, P: JointPrefix, L, R> UnionItem<'a, P, L, R> {
718 fn from_p1(value: crate::trieview::UnionItem<'a, P::P1, L, R>) -> Self {
719 match value {
720 crate::trieview::UnionItem::Left {
721 prefix,
722 left,
723 right,
724 } => UnionItem::Left {
725 prefix: P::from_p1(prefix),
726 left,
727 right: right.map(|(p, r)| (P::from_p1(p), r)),
728 },
729 crate::trieview::UnionItem::Right {
730 prefix,
731 left,
732 right,
733 } => UnionItem::Right {
734 prefix: P::from_p1(prefix),
735 left: left.map(|(p, l)| (P::from_p1(p), l)),
736 right,
737 },
738 crate::trieview::UnionItem::Both {
739 prefix,
740 left,
741 right,
742 } => UnionItem::Both {
743 prefix: P::from_p1(prefix),
744 left,
745 right,
746 },
747 }
748 }
749
750 fn from_p2(value: crate::trieview::UnionItem<'a, P::P2, L, R>) -> Self {
751 match value {
752 crate::trieview::UnionItem::Left {
753 prefix,
754 left,
755 right,
756 } => UnionItem::Left {
757 prefix: P::from_p2(prefix),
758 left,
759 right: right.map(|(p, r)| (P::from_p2(p), r)),
760 },
761 crate::trieview::UnionItem::Right {
762 prefix,
763 left,
764 right,
765 } => UnionItem::Right {
766 prefix: P::from_p2(prefix),
767 left: left.map(|(p, l)| (P::from_p2(p), l)),
768 right,
769 },
770 crate::trieview::UnionItem::Both {
771 prefix,
772 left,
773 right,
774 } => UnionItem::Both {
775 prefix: P::from_p2(prefix),
776 left,
777 right,
778 },
779 }
780 }
781}
782
783/// An iterator over the intersection of two [`JointPrefixMap`]s. The iterator yields first prefixes
784/// of `P1`, followed by those of `P2`.
785pub struct Intersection<'a, P: JointPrefix, L, R> {
786 pub(crate) i1: Option<crate::trieview::Intersection<'a, P::P1, L, R>>,
787 pub(crate) i2: Option<crate::trieview::Intersection<'a, P::P2, L, R>>,
788}
789
790impl<'a, P: JointPrefix, L, R> Iterator for Intersection<'a, P, L, R> {
791 type Item = (P, &'a L, &'a R);
792
793 fn next(&mut self) -> Option<Self::Item> {
794 if let Some(i1) = self.i1.as_mut() {
795 if let Some((p, l, r)) = i1.next() {
796 return Some((P::from_p1(p), l, r));
797 }
798 self.i1 = None;
799 }
800 if let Some(i2) = self.i2.as_mut() {
801 if let Some((p, l, r)) = i2.next() {
802 return Some((P::from_p2(p), l, r));
803 }
804 self.i2 = None;
805 }
806 None
807 }
808}
809
810/// An iterator over the difference of two [`JointPrefixMap`]s, i.e., prefixes that are in `self`
811/// but not in `other`. The iterator yields first prefixes of `P1`, followed by those of `P2`.
812pub struct Difference<'a, P: JointPrefix, L, R> {
813 pub(crate) i1: Option<crate::trieview::Difference<'a, P::P1, L, R>>,
814 pub(crate) i2: Option<crate::trieview::Difference<'a, P::P2, L, R>>,
815}
816
817impl<'a, P: JointPrefix, L, R> Iterator for Difference<'a, P, L, R> {
818 type Item = DifferenceItem<'a, P, L, R>;
819
820 fn next(&mut self) -> Option<Self::Item> {
821 if let Some(i1) = self.i1.as_mut() {
822 if let Some(next) = i1.next() {
823 return Some(DifferenceItem::from_p1(next));
824 }
825 self.i1 = None;
826 }
827 if let Some(i2) = self.i2.as_mut() {
828 if let Some(next) = i2.next() {
829 return Some(DifferenceItem::from_p2(next));
830 }
831 self.i2 = None;
832 }
833 None
834 }
835}
836
837/// An iterator over the covering difference of two [`JointPrefixMap`]s, i.e., prefixes of `self` that
838/// are not covered by `other`. The iterator yields first prefixes of `P1`, followed by those of
839/// `P2`.
840pub struct CoveringDifference<'a, P: JointPrefix, L, R> {
841 pub(crate) i1: Option<crate::trieview::CoveringDifference<'a, P::P1, L, R>>,
842 pub(crate) i2: Option<crate::trieview::CoveringDifference<'a, P::P2, L, R>>,
843}
844
845impl<'a, P: JointPrefix, L, R> Iterator for CoveringDifference<'a, P, L, R> {
846 type Item = (P, &'a L);
847
848 fn next(&mut self) -> Option<Self::Item> {
849 if let Some(i1) = self.i1.as_mut() {
850 if let Some((p, l)) = i1.next() {
851 return Some((P::from_p1(p), l));
852 }
853 self.i1 = None;
854 }
855 if let Some(i2) = self.i2.as_mut() {
856 if let Some((p, l)) = i2.next() {
857 return Some((P::from_p2(p), l));
858 }
859 self.i2 = None;
860 }
861 None
862 }
863}
864
865/// An item of the [`Difference`] iterator.
866#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
867pub struct DifferenceItem<'a, P, L, R> {
868 /// The prefix that is present in `self` but not in `other`.
869 pub prefix: P,
870 /// The value stored in `self`.
871 pub value: &'a L,
872 /// The longest-prefix-match that is present in `other`.
873 pub right: Option<(P, &'a R)>,
874}
875
876impl<'a, P: JointPrefix, L, R> DifferenceItem<'a, P, L, R> {
877 fn from_p1(value: crate::trieview::DifferenceItem<'a, P::P1, L, R>) -> Self {
878 Self {
879 prefix: P::from_p1(value.prefix),
880 value: value.value,
881 right: value.right.map(|(p, r)| (P::from_p1(p), r)),
882 }
883 }
884
885 fn from_p2(value: crate::trieview::DifferenceItem<'a, P::P2, L, R>) -> Self {
886 Self {
887 prefix: P::from_p2(value.prefix),
888 value: value.value,
889 right: value.right.map(|(p, r)| (P::from_p2(p), r)),
890 }
891 }
892}