pub struct Node<T> {
element: T,
next: Link<T>,
}
type Link<T> = Option<Box<Node<T>>>;
pub struct List<T> {
head: Link<T>,
}
impl<T> List<T> {
pub fn new() -> Self {
List { head: None }
}
pub fn push(&mut self, item: T) {
self.push_node(Box::new(Node {
element: item,
next: None,
}));
}
pub fn push_node(&mut self, mut node: Box<Node<T>>) {
node.next = self.head.take();
self.head = Some(node);
}
pub fn pop(&mut self) -> Option<T> {
self.pop_node().map(|node| node.element)
}
pub fn pop_node(&mut self) -> Option<Box<Node<T>>> {
self.head.take().map(|mut node| {
self.head = node.next.take();
node
})
}
pub fn peek(&self) -> Option<&T> {
self.head.as_ref().map(|node| &node.element)
}
pub fn peek_mut(&mut self) -> Option<&mut T> {
self.head.as_mut().map(|node| &mut node.element)
}
pub fn iter_into(self) -> IterInto<T> {
IterInto(self)
}
pub fn iter(&self) -> Iter<T> {
Iter(self.head.as_deref())
}
pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut(self.head.as_deref_mut())
}
}
impl<T> Drop for List<T> {
fn drop(&mut self) {
while let Some(h) = self.head.take() {
self.head = h.next;
}
}
}
pub struct IterInto<T>(List<T>);
impl<T> Iterator for IterInto<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.0.pop()
}
}
pub struct Iter<'a, T: 'a>(Option<&'a Node<T>>);
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.0.map(|current| {
self.0 = current.next.as_deref();
¤t.element
})
}
}
pub struct IterMut<'a, T: 'a>(Option<&'a mut Node<T>>);
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
self.0.take().map(|current| {
self.0 = current.next.as_deref_mut();
&mut current.element
})
}
}
#[cfg(test)]
mod test {
use super::List;
#[test]
fn basics() {
let mut list: List<i32> = List::new();
assert_eq!(list.pop(), None);
list.push(1);
list.push(2);
list.push(3);
assert_eq!(list.peek(), Some(&3));
assert_eq!(list.peek_mut(), Some(&mut 3));
list.peek_mut().map(|value| *value = 10);
assert_eq!(list.peek(), Some(&10));
assert_eq!(list.pop(), Some(10));
assert_eq!(list.pop(), Some(2));
assert_eq!(list.pop(), Some(1));
assert_eq!(list.pop(), None);
}
#[test]
fn iter_mut() {
let mut list: List<i32> = List::new();
list.push(1);
list.push(2);
list.push(3);
list.push(4);
for item in list.iter_mut() {
*item += 1;
}
let mut iter = list.iter();
assert_eq!(iter.next(), Some(&5));
assert_eq!(iter.next(), Some(&4));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), Some(&2));
}
#[test]
fn iter() {
let mut list: List<i32> = List::new();
list.push(1);
list.push(2);
list.push(3);
list.push(4);
let mut iter = list.iter();
assert_eq!(iter.next(), Some(&4));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&1));
}
#[test]
fn iter_into() {
let mut list: List<i32> = List::new();
list.push(1);
list.push(2);
list.push(3);
list.push(4);
let mut iter = list.iter_into();
assert_eq!(iter.next(), Some(4));
assert_eq!(iter.next(), Some(3));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), Some(1));
}
}