simple_ringbuf 0.1.2

Simple Ringbuf is a speedy lightweight fixed-size infinite-use collection optimized for straightforward single threaded use.
Documentation
//! Provides iterator implementation for a [`RingBuf`].
//!
//! [`RingBuf`]: ..\struct.RingBuffer.html

use std::iter::{DoubleEndedIterator, ExactSizeIterator, IntoIterator, Iterator};

use super::RingBuffer;

/// A non-consuming [`RingBuf`] iterator.
///
/// [`RingBuf`]: ..\struct.RingBuffer.html
pub struct RingBufIter<'a, T> {
    front_idx: isize,
    back_idx: isize,
    buf: &'a RingBuffer<T>,
}

impl<'a, T> RingBufIter<'a, T> {
    pub fn new(buf: &'a RingBuffer<T>) -> Self {
        RingBufIter {
            buf,
            front_idx: 0,
            back_idx: buf.len as isize - 1,
        }
    }
}

impl<'a, T> Iterator for RingBufIter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        if self.front_idx > self.back_idx {
            None
        } else {
            let elem = &self.buf[self.front_idx as usize];
            self.front_idx += 1;
            Some(elem)
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len(), Some(self.len()))
    }
}

impl<'a, T> ExactSizeIterator for RingBufIter<'a, T> {
    fn len(&self) -> usize {
        ((self.back_idx + 1) - self.front_idx).max(0) as usize
    }
}

impl<'a, T> DoubleEndedIterator for RingBufIter<'a, T> {
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.back_idx < self.front_idx {
            None
        } else {
            let elem = &self.buf[self.back_idx as usize];
            self.back_idx -= 1;
            Some(elem)
        }
    }
}

/// A consuming/moving [`RingBuf`] iterator.
///
/// [`RingBuf`]: ..\struct.RingBuffer.html
pub struct RingBufIntoIter<T> {
    pub buf: RingBuffer<T>,
}

impl<T> Iterator for RingBufIntoIter<T> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        self.buf.pop()
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len(), Some(self.len()))
    }
}

impl<T> ExactSizeIterator for RingBufIntoIter<T> {
    fn len(&self) -> usize {
        self.buf.len
    }
}

impl<T> DoubleEndedIterator for RingBufIntoIter<T> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.buf.pop_oldest()
    }
}

impl<'a, T> IntoIterator for &'a RingBuffer<T> {
    type Item = &'a T;
    type IntoIter = RingBufIter<'a, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

impl<T> IntoIterator for RingBuffer<T> {
    type Item = T;
    type IntoIter = RingBufIntoIter<T>;

    fn into_iter(self) -> Self::IntoIter {
        RingBufIntoIter { buf: self }
    }
}