algorithmica 0.1.10

Rust Algorithms
Documentation
type Link<Item> = *mut Node<Item>;
struct Node<Item> {
    value: Item,
    next: Link<Item>,
}

pub struct List<Item> {
    head: Link<Item>,
}

pub struct Iter<'a, Item> {
    current: Option<&'a Node<Item>>,
}

pub struct IterMut<'a, Item> {
    current: Option<&'a mut Node<Item>>,
}

impl<Item> List<Item> {
    pub fn new() -> Self {
        Default::default()
    }

    pub fn push_front(&mut self, value: Item) {
        let new_node = Box::into_raw(Box::new(Node {
            value,
            next: std::ptr::null_mut(),
        }));

        if self.head.is_null() {
            self.head = new_node;
        } else {
            unsafe {
                let node = &mut *new_node;
                node.next = self.head;
                self.head = node;
            }
        }
    }

    pub fn pop_front(&mut self) -> Option<Item> {
        if self.head.is_null() {
            None
        } else {
            unsafe {
                let box_node = Box::from_raw(self.head);
                self.head = box_node.next;
                Some(box_node.value)
            }
        }
    }

    pub fn peek(&self) -> Option<&Item> {
        unsafe { self.head.as_ref().map(|x| &x.value) }
    }

    pub fn peek_mut(&mut self) -> Option<&mut Item> {
        unsafe { self.head.as_mut().map(|x| &mut x.value) }
    }

    pub fn iter<'a>(&self) -> Iter<'a, Item> {
        Iter {
            current: unsafe { self.head.as_ref() },
        }
    }

    pub fn iter_mut<'a>(&mut self) -> IterMut<'a, Item> {
        IterMut {
            current: unsafe { self.head.as_mut() },
        }
    }
}

impl<Item> Drop for List<Item> {
    fn drop(&mut self) {
        while self.pop_front().is_some() {}
    }
}

impl<Item> Default for List<Item> {
    fn default() -> Self {
        Self {
            head: std::ptr::null_mut(),
        }
    }
}

impl<'a, Item> Iterator for Iter<'a, Item> {
    type Item = &'a Item;
    fn next(&mut self) -> Option<Self::Item> {
        self.current.take().map(|x| {
            self.current = unsafe { x.next.as_ref() };
            &x.value
        })
    }
}

impl<'a, Item> Iterator for IterMut<'a, Item> {
    type Item = &'a mut Item;
    fn next(&mut self) -> Option<Self::Item> {
        self.current.take().map(|x| {
            self.current = unsafe { x.next.as_mut() };
            &mut x.value
        })
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn push() {
        let mut ll = super::List::new();
        ll.push_front(1);
        ll.push_front(2);
    }

    #[test]
    fn peek_1() {
        let ll = super::List::<i32>::new();
        assert_eq!(ll.peek(), None)
    }

    #[test]
    fn peek_2() {
        let mut ll = super::List::<i32>::new();
        ll.push_front(1);
        assert_eq!(ll.peek(), Some(&1))
    }

    #[test]
    fn pop() {
        let mut ll = super::List::new();
        ll.push_front(1);
        ll.push_front(2);
        assert_eq!(ll.pop_front(), Some(2));
        assert_eq!(ll.pop_front(), Some(1));
    }

    #[test]
    fn iter() {
        let mut ll = super::List::new();
        ll.push_front(1);
        ll.push_front(2);
        let mut iter = ll.iter();
        assert_eq!(iter.next(), Some(&2));
        assert_eq!(iter.next(), Some(&1));
        assert_eq!(iter.next(), None);
    }

    #[test]
    fn iter_mut() {
        let mut ll = super::List::new();
        ll.push_front(1);
        ll.push_front(2);
        for x in ll.iter_mut() {
            *x += 1;
        }
        let mut iter = ll.iter();
        assert_eq!(iter.next(), Some(&3));
        assert_eq!(iter.next(), Some(&2));
        assert_eq!(iter.next(), None);
    }
}