agenda 0.0.1

Safe collections that can be mutated while being iterated through
Documentation
//! 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))
    }
}