use std::fmt::{self, Display};
#[derive(Clone)]
pub struct List<T> {
head: Link<T>,
}
type Link<T> = Option<Box<Node<T>>>;
#[derive(Clone)]
struct Node<T> {
elem: T,
next: Link<T>,
}
impl<T> List<T> {
pub fn new() -> Self {
List { head: None }
}
pub fn add(self, items: impl IntoIterator<Item = T>) -> Self {
let mut temp = List::new();
for item in items {
temp = temp.push(item);
}
self.append(temp.reverse())
}
pub fn push(mut self, elem: T) -> Self {
let new_node = Box::new(Node {
elem,
next: self.head.take(),
});
self.head = Some(new_node);
self
}
pub fn append(mut self, mut other: Self) -> Self {
if self.head.is_none() {
return other;
}
let mut current = &mut self.head;
while let Some(node) = current {
if node.next.is_none() {
node.next = other.head.take();
break;
}
current = &mut node.next;
}
self
}
pub fn reverse(mut self) -> Self {
let mut reversed = List::new();
while let Some(node) = self.head.take() {
reversed = reversed.push(node.elem);
self.head = node.next;
}
reversed
}
pub fn len(&self) -> usize {
self.iter().count()
}
pub fn is_empty(&self) -> bool {
self.head.is_none()
}
pub fn iter(&self) -> ListIter<'_, T> {
ListIter {
next: self.head.as_deref(),
}
}
}
pub struct ListIter<'a, T> {
pub(crate) next: Option<&'a Node<T>>,
}
impl<'a, T> Iterator for ListIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.next.map(|node| {
self.next = node.next.as_deref();
&node.elem
})
}
}
pub struct ListIterMut<'a, T> {
pub(crate) next: Option<&'a mut Node<T>>,
}
impl<'a, T> Iterator for ListIterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
self.next.take().map(|node| {
self.next = node.next.as_deref_mut();
&mut node.elem
})
}
}
pub struct IntoListIter<T> {
current: Option<Box<Node<T>>>,
}
impl<T> Iterator for IntoListIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.current.take().map(|node| {
let node = *node;
self.current = node.next;
node.elem
})
}
}
impl<T> IntoIterator for List<T> {
type Item = T;
type IntoIter = IntoListIter<T>;
fn into_iter(self) -> Self::IntoIter {
IntoListIter { current: self.head }
}
}
impl<'a, T> IntoIterator for &'a List<T> {
type Item = &'a T;
type IntoIter = ListIter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut List<T> {
type Item = &'a mut T;
type IntoIter = ListIterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
ListIterMut {
next: self.head.as_deref_mut(),
}
}
}
impl<T: Display> Display for List<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut first = true;
write!(f, "[")?;
for item in self.iter() {
if !first {
write!(f, ", ")?;
}
write!(f, "{}", item)?;
first = false;
}
write!(f, "]")
}
}