#![allow(unused)]
mod node;
use node::*;
#[derive(Default)]
pub struct AList<T> {
head: Option<StrongNode<T>>,
tail: Option<WeakNode<T>>,
len: usize,
}
impl<T> AList<T> {
pub fn new() -> Self {
AList { head: None, tail: None, len: 0 }
}
pub fn from(data: T) -> Self {
let node = Node::new(data);
AList {
tail: Some(Rc::downgrade(&node)),
head: Some(node),
len: 1,
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn map_head<C: FnOnce(&T) -> R, R>(&self, closure: C) -> Option<R> {
self.head.as_ref().map(|rc| {
closure(rc.borrow().data())
})
}
pub fn push(&mut self, data: T) {
let mut new_head = Node::new_head(data, self.head.clone());
if let Some(node) = self.head.as_mut() {
node.borrow_mut().set_prev(Some(Rc::clone(&new_head)));
} else {
self.tail = Some(Rc::downgrade(&new_head));
}
self.head = Some(new_head);
self.len += 1;
}
pub fn pop(&mut self) -> Option<T> {
let mut node = Rc::try_unwrap(self.head.take()?)
.map(|wrapper| { wrapper.into_inner() })
.unwrap_or_else(|_| {
panic!("head should have no other owners. If you see this, it's a bug.")
});
self.head = node
.take_next()
.inspect(|new_head| {
new_head.borrow_mut().clear_prev();
});
if self.head.is_none() {
self.tail = None
}
self.len -= 1;
Some(node.into_data())
}
pub fn push_back(&mut self, data: T) {
match self.tail.as_mut() {
Some(tail) => {
let old_tail = tail.upgrade();
let node = Node::new_tail(data, old_tail.clone());
self.tail = Some(Rc::downgrade(&node));
old_tail.unwrap().borrow_mut().set_next(Some(node.clone()));
},
None if self.head.is_none() => {
let node = Node::new(data);
self.tail = Some(Rc::downgrade(&node));
self.head = Some(node);
},
None => { panic!("If tail is None, head should also be None. If you reached this, it's a bug.")},
}
self.len += 1;
}
pub fn pop_back(&mut self) -> Option<T> {
self.tail.as_ref()?;
let mut tail = self
.tail
.take()
.and_then(|weak| weak.upgrade())
.unwrap();
let new_tail = tail.borrow_mut().take_prev();
if new_tail.is_none() { self.head.take(); }
self.tail = new_tail.as_ref().map(|rc| {
rc.borrow_mut().clear_next();
Rc::downgrade(rc)
});
self.len -= 1;
Some(Rc::try_unwrap(tail)
.unwrap_or_else(|_| {
panic!("Nothing should own this node, if you see this it's a bug")
})
.into_inner()
.into_data())
}
}