1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
use std::fmt; use std::net::Ipv4Addr; /// A smart IPv4 iterator. /// /// A smart iterator is an iterator that doesn't store all the items in memory. It's usefull for long series. /// /// # Examples /// /// ``` /// use std::net::Ipv4Addr; /// /// use net_adds::Ipv4AddrSmartIterator; /// /// let mut iter = Ipv4AddrSmartIterator::new(Ipv4Addr::from(0), Ipv4Addr::from(1)); /// /// assert_eq!(iter.next(), Some(Ipv4Addr::new(0, 0, 0, 0))); /// assert_eq!(iter.next(), Some(Ipv4Addr::new(0, 0, 0, 1))); /// assert_eq!(iter.next(), None); /// /// let mut iter = Ipv4AddrSmartIterator::new(Ipv4Addr::from(0), Ipv4Addr::from(0)); /// /// assert_eq!(iter.next(), Some(Ipv4Addr::new(0, 0, 0, 0))); /// assert_eq!(iter.next(), None); /// /// let mut iter = Ipv4AddrSmartIterator::new(Ipv4Addr::from(1), Ipv4Addr::from(0)); /// /// assert_eq!(iter.next(), Some(Ipv4Addr::new(0, 0, 0, 1))); /// assert_eq!(iter.next(), Some(Ipv4Addr::new(0, 0, 0, 0))); /// assert_eq!(iter.next(), None); /// ``` #[derive(Clone, Debug)] pub struct Ipv4AddrSmartIterator { start: u32, end: u32, curr: u32, next: Option<u32>, updater: fn(u32) -> u32 } impl Ipv4AddrSmartIterator { /// Returns a `Ipv4AddrSmartIterator`. pub fn new (start: Ipv4Addr, end: Ipv4Addr) -> Ipv4AddrSmartIterator { let start = u32::from(start); let end = u32::from(end); let updater = if start < end { |x| x + 1 } else { |x| x - 1 }; Ipv4AddrSmartIterator { start, end, curr: start.clone(), next: Some(start.clone()), updater } } } impl Iterator for Ipv4AddrSmartIterator { type Item = Ipv4Addr; fn next (&mut self) -> Option<Self::Item> { self.curr = self.next?; let update = self.updater; self.next = if self.curr == self.end { None } else { Some(update(self.curr)) }; Some(Ipv4Addr::from(self.curr)) } } impl fmt::Display for Ipv4AddrSmartIterator { fn fmt (&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}-{}-{}", self.start, self.curr, self.end) } } impl From<(Ipv4Addr, Ipv4Addr)> for Ipv4AddrSmartIterator { /// Create an `Ipv4AddrSmartIterator` from a tuple `(Ipv4Addr, Ipv4Addr)`. /// /// # Examples: /// /// ``` /// use std::net::Ipv4Addr; /// /// use net_adds::Ipv4AddrSmartIterator; /// /// let mut iter = Ipv4AddrSmartIterator::from((Ipv4Addr::from(0), Ipv4Addr::from(1))); /// /// assert_eq!(iter.next(), Some(Ipv4Addr::from(0))); /// assert_eq!(iter.next(), Some(Ipv4Addr::from(1))); /// assert_eq!(iter.next(), None); /// ``` fn from (ips: (Ipv4Addr, Ipv4Addr)) -> Ipv4AddrSmartIterator { Ipv4AddrSmartIterator::new(ips.0, ips.1) } }