use std::{ptr::NonNull};
pub struct Node <T> {
element: T,
prev: Option<NonNull<Node<T>>>,
next: Option<NonNull<Node<T>>>,
}
impl <T> Node<T> {
fn new (element: T) -> Node<T> {
Node { element, prev: None, next: None }
}
}
pub struct Iterator<T> {
itr: Option<NonNull<Node<T>>>,
}
impl <T> Iterator<T> {
pub fn new(first: Option<NonNull<Node<T>>>) -> Self {
Iterator{ itr: first }
}
pub fn hasNext(&self) -> bool {
match self.itr {
None => false,
Some(itr) => true,
}
}
pub fn next(&mut self) -> Option<&T> {
match self.itr {
None => None,
Some(itr) => {
unsafe {
let element = &(*itr.as_ptr()).element;
self.itr = (*itr.as_ptr()).next;
Some(element)
}
}
}
}
}
pub struct LinkedList <T> {
length: usize,
head: Option<NonNull<Node<T>>>,
tail: Option<NonNull<Node<T>>>,
}
impl <T> LinkedList<T> {
pub fn new () -> Self {
LinkedList { length: 0, head: None, tail: None }
}
pub fn add(&mut self, element: T) {
let mut node = Box::new(Node::new(element));
node.next = None;
node.prev = self.tail;
let node = Some(Box::leak(node).into());
match self.tail {
None => self.head = node,
Some(tail) => {
unsafe {
(*tail.as_ptr()).next = node;
}
}
}
self.tail = node;
self.length += 1;
}
pub fn size(&mut self) -> usize {
self.length
}
pub fn iterator(& self) -> Iterator<T> {
Iterator::new(self.head)
}
}
#[cfg(test)]
mod tests {
use super::LinkedList;
#[test]
fn add() {
let mut list : LinkedList<usize> = LinkedList::new();
list.add(7);
assert_eq!(list.size(), 1);
list.add(8);
let mut itr = list.iterator();
if itr.hasNext() {
match itr.next() {
None => {},
Some(element) => assert_eq!(*element, 7)
}
}
}
}