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
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
//! Convenient collection that allows safe mutation during iteration
//!
//! `Agenda` offers queue-like functionality but has interior mutability to
//! permit pushing and popping inside a for-loop.
//!
//! ```rust
//! use agenda::Queue;
//!
//! fn iter(queue: Queue<String>) {
//!     for item in queue.iter() {
//!         match item.as_str() {
//!             "three" => queue.push(String::from("two")),
//!             "two" => queue.push(String::from("one")),
//!             "one" => queue.push(String::from("zero")),
//!             _ => {},
//!         }
//!     }
//! }
//!
//! ```
//!

use std::cell::RefCell;
use std::iter::FromIterator;
use std::collections::VecDeque;

#[cfg(test)] mod test;


/// A queue which can be modified while being iterated through.
///
/// A `Queue` uses a `VecDeque` under the hood, which means quick operations,
/// cache locality, and amortized allocations.
///
/// `push`ing an element adds it to the end of the queue, and `pop`ping removes
/// it from the front. To iterate through the most recently `push`ed elements
/// first, iterate through elements in `queue.iter().rev()`.
#[derive(Debug, Default)]
pub struct Queue<T>(RefCell<VecDeque<T>>);

impl<T> Queue<T> {
    /// Construct an empty with the default `VecDeque` capacity (currently 7)
    pub fn new() -> Queue<T> {
        Queue(RefCell::new(VecDeque::new()))
    }

    /// Specify the initial capacity
    pub fn with_capacity(n: usize) -> Queue<T> {
        Queue(RefCell::new(VecDeque::with_capacity(n)))
    }

    /// Append an element to the end of the queue. 
    pub fn push(&self, new: T) {
        let mut inner = self.0.borrow_mut();
        inner.push_back(new);
    }

    /// Pop the first element of the queue or return `None` if it's empty
    pub fn pop(&self) -> Option<T> {
        let mut inner = self.0.borrow_mut();
        inner.pop_front()
    }

    /// Pop the last element of the queue or return `None` if it's empty
    pub fn pop_back(&self) -> Option<T> {
        let mut inner = self.0.borrow_mut();
        inner.pop_back()
    }

    /// Iterate through the queue. 
    /// `for i in queue.iter()` is the same as `for i in &queue`
    pub fn iter(&self) -> &Self {
        self
    }
}

/// For ownership reasons, `Iterator` is implemented over `&Queue`.
impl<'a, T> Iterator for &'a Queue<T> {
    type Item = T;
    fn next(&mut self) -> Option<T> { self.pop() }
}

impl<'a, T> DoubleEndedIterator for &'a Queue<T> {
    fn next_back(&mut self) -> Option<T> {
        self.pop_back()
    }
}

impl<'a, T> ExactSizeIterator for &'a Queue<T> {
    fn len(&self) -> usize {
        self.0.borrow().len()
    }
}

impl<'a, T> Extend<T> for &'a Queue<T> {
    fn extend<S: IntoIterator<Item=T>>(&mut self, iter: S) {
        let mut inner = self.0.borrow_mut();
        inner.extend(iter);
    }
}

impl<'a, T> FromIterator<T> for Queue<T> {
    fn from_iter<S: IntoIterator<Item=T>>(iter: S) -> Queue<T> {
        let vd = VecDeque::from_iter(iter);
        Queue(RefCell::new(vd))
    }
}