squeue 0.10.3

SQueue is a sized queue.
Documentation
// Copyright (C) 2024 Christian Mauduit <ufoot@ufoot.org>

use crate::queue::Queue;
use std::collections::VecDeque;
use std::iter::FusedIterator;

/// Iterator which drains a FIFO queue.
///
/// Use this when you want to get all the items, at a given point,
/// and free space in the queue.
///
/// ```
/// use squeue::Queue;
///
/// let mut queue = Queue::new(10);
/// queue.push(1);
/// queue.push(10);
/// let drain = queue.drain();
/// assert_eq!(0, queue.len());
/// for i in drain {
///     println!("{}", i);
/// }
/// ```
#[derive(Debug, Clone)]
pub struct Drain<T> {
    queue: VecDeque<T>,
}

impl<T> Drain<T> {
    /// Create a drain from a FIFO queue.
    ///
    /// Use this when you want to get all the items, at a given point,
    /// and free space in the queue.
    ///
    /// ```
    /// use squeue::{Queue, Drain};
    ///
    /// let mut queue = Queue::new(10);
    /// queue.push(1);
    /// queue.push(10);
    /// let drain = Drain::new(&mut queue);
    /// assert_eq!(0, queue.len());
    /// for i in drain {
    ///     println!("{}", i);
    /// }
    /// ```
    pub fn new(old_queue: &mut Queue<T>) -> Self {
        let mut new_queue = VecDeque::with_capacity(old_queue.len());
        loop {
            match old_queue.pop() {
                Some(v) => new_queue.push_back(v),
                None => break,
            }
        }
        Drain { queue: new_queue }
    }
}

impl<T> Drain<T> {
    pub fn len(&self) -> usize {
        self.queue.len()
    }
}

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

    fn next(&mut self) -> Option<T> {
        self.queue.pop_front()
    }

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

impl<T> ExactSizeIterator for Drain<T> {}
impl<T> FusedIterator for Drain<T> {}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_drain() {
        let mut queue: Queue<usize> = Queue::new(10);
        assert_eq!(None, queue.push(4));
        assert_eq!(None, queue.push(42));
        assert_eq!(None, queue.push(421));
        let mut drain = queue.drain();
        assert_eq!(0, queue.len());
        assert_eq!(None, queue.push(7));
        assert_eq!(Some(4), drain.next());
        assert_eq!(Some(42), drain.next());
        assert_eq!(Some(421), drain.next());
        assert_eq!(None, drain.next());
        assert_eq!(Some(7), queue.pop());
        assert_eq!(None, queue.pop());
    }
}