ixlist 0.1.0

The “ixlist” is a linked list in a vector, or if you want a list in a pond or an arena-allocated linked index-chasing fest. Implements a queue interface and a cursor.
Documentation
extern crate itertools as it;
extern crate ixlist;

use ixlist::{
    List,
    Seek,
};

#[test]
fn basic()
{
    let l: List<i32> = List::new();
    assert_eq!(l.len(), 0);
}

#[test]
fn push_pop()
{
    let mut l = List::new();
    assert_eq!(l.pop_front(), None);
    assert_eq!(l.pop_back(), None);

    l.push_back(1);
    l.push_back(2);
    l.push_back(3);
    assert_eq!(l.len(), 3);
    assert_eq!(l.pop_back(), Some(3));
    assert_eq!(l.pop_front(), Some(1));
    assert_eq!(l.pop_front(), Some(2));
    assert_eq!(l.pop_back(), None);
    assert_eq!(l.pop_front(), None);

    l.push_front(1);
    l.push_front(2);
    l.push_front(3);
    assert_eq!(l.len(), 3);
    assert_eq!(l.pop_back(), Some(1));
    assert_eq!(l.pop_front(), Some(3));
    assert_eq!(l.pop_front(), Some(2));
    assert_eq!(l.pop_back(), None);
    assert_eq!(l.pop_front(), None);
}

#[test]
fn iter()
{
    let mut l = List::new();
    l.push_back(2);
    l.push_front(1);
    l.push_back(3);
    assert_eq!(l.iter().count(), 3);
    assert_eq!(l.iter().rev().count(), 3);
    assert_eq!(l.iter_mut().count(), 3);
    assert_eq!(l.iter_mut().rev().count(), 3);
    it::assert_equal(l.iter(), &[1,2,3]);
    it::assert_equal(l.iter().rev(), &[3,2,1]);
    it::assert_equal(l.iter_mut(), &[1,2,3]);
    it::assert_equal(l.iter_mut().rev(), &[3,2,1]);
}

#[test]
fn cursor()
{
    let mut l = List::new();
    for index in 0..5 {
        l.push_back(index)
    }
    {
        let mut c = l.cursor();
        assert_eq!(c.next(), Some(&mut 0));
        assert_eq!(c.prev(), Some(&mut 0));
        assert_eq!(c.prev(), None);
        assert_eq!(c.prev(), Some(&mut 4));
        c.insert(77);
        assert_eq!(c.next(), Some(&mut 77));
        assert_eq!(c.next(), Some(&mut 4));
    }
    it::assert_equal(l.iter(), &[0, 1, 2, 3, 77, 4]);
    it::assert_equal(l.iter().rev(), &[4, 77, 3, 2, 1, 0]);

    {
        let mut c = l.cursor();
        c.seek(Seek::Forward(2));
        c.insert(20);
    }
    it::assert_equal(l.iter(), &[0, 1, 20, 2, 3, 77, 4]);
    it::assert_equal(l.iter().rev(), &[4, 77, 3, 2, 20, 1, 0]);

    {
        let mut c = l.cursor();
        c.seek(Seek::Forward(2));
        c.seek(Seek::Tail);
        c.insert(30);
    }
    it::assert_equal(l.iter(), &[0, 1, 20, 2, 3, 77, 4, 30]);
    it::assert_equal(l.iter().rev(), &[30, 4, 77, 3, 2, 20, 1, 0]);

    let mut l = List::new();
    {
        let mut c = l.cursor();
        c.insert(0);
        c.seek(Seek::Tail);
        c.insert(1);
        c.seek(Seek::Head);
        c.insert(2);
        c.seek(Seek::Forward(100));
        c.insert(3);
        c.seek(Seek::Backward(1));
        c.insert(4);
    }
    it::assert_equal(l.iter(), &[2, 0, 4, 1, 3]);
    it::assert_equal(l.iter().rev(), &[3, 1, 4, 0, 2]);

    l.linearize();

    it::assert_equal(l.iter(), &[2, 0, 4, 1, 3]);
    it::assert_equal(l.iter().rev(), &[3, 1, 4, 0, 2]);

    // test wrap around with .next()
    let mut l = List::new();
    {
        let mut c = l.cursor();
        c.insert(0);
        c.insert(1);
        assert!(c.next().is_some());
        assert!(c.next().is_some());
        assert!(c.next().is_none());
        assert!(c.next().is_some());
        c.insert(-1);
    }
    it::assert_equal(l.iter(), &[1, -1, 0]);
    it::assert_equal(l.iter().rev(), &[0, -1, 1]);
}

#[test]
fn extend()
{
    let mut l = List::new();
    l.push_front(1);
    l.extend(2..2);
    it::assert_equal(l.iter(), &[1]);
    it::assert_equal(l.iter().rev(), &[1]);

    l.extend(2..5);
    it::assert_equal(l.iter(), &[1, 2, 3, 4]);
    it::assert_equal(l.iter().rev(), &[4, 3, 2, 1]);
}

#[test]
fn from_iter()
{
    let l: List<_> = (0..5).collect();
    it::assert_equal(l.iter(), &[0, 1, 2, 3, 4]);
}