use std::cell;
use std::rc;
pub struct Node
{
data : isize,
next : Option<rc::Rc<cell::RefCell<Node>>>,
previous : Option<rc::Weak<cell::RefCell<Node>>>
}
pub struct DoubleLinkedList
{
head : Option<rc::Rc<cell::RefCell<Node>>>,
foot : Option<rc::Rc<cell::RefCell<Node>>>
}
impl DoubleLinkedList
{
pub fn new() -> Self
{
return Self { head : None, foot : None};
}
fn new_node(value : isize) -> rc::Rc<cell::RefCell<Node>>
{
let node_refcell : cell::RefCell<Node> = cell::RefCell::new(Node{ data : value, next : None, previous : None });
return rc::Rc::new(node_refcell);
}
pub fn push(&mut self, v : isize)
{
let node_refcell_rc : rc::Rc<cell::RefCell<Node>> = DoubleLinkedList::new_node(v);
match self.foot.take()
{
None =>
{
self.foot = Some(rc::Rc::clone(&node_refcell_rc));
self.head = Some(node_refcell_rc);
},
Some(previous_foot_node_refcell_rc) =>
{
self.foot = Some(rc::Rc::clone(&node_refcell_rc));
node_refcell_rc.borrow_mut().previous = Some(rc::Rc::downgrade(&previous_foot_node_refcell_rc));
previous_foot_node_refcell_rc.borrow_mut().next = Some(node_refcell_rc);
}
}
}
pub fn insert_head(&mut self, value : isize)
{
let new_node_refcell_rc : rc::Rc<cell::RefCell<Node>> = DoubleLinkedList::new_node(value);
match self.head.take()
{
None =>
{
self.foot = Some(rc::Rc::clone(&new_node_refcell_rc));
self.head = Some(new_node_refcell_rc);
},
Some(previous_head_refcell_rc) =>
{
previous_head_refcell_rc.borrow_mut().previous = Some(rc::Rc::downgrade(&new_node_refcell_rc));
new_node_refcell_rc.borrow_mut().next = Some(previous_head_refcell_rc);
self.head = Some(new_node_refcell_rc);
}
}
}
pub fn iter(&mut self) -> ListIter
{
return match &self.head
{
None => ListIter { cur : None },
Some(head_refcell_rc) =>
{
let head : rc::Rc<cell::RefCell<Node>> = rc::Rc::clone(&head_refcell_rc);
ListIter { cur : Some(head) }
},
};
}
}
pub struct ListIter
{
pub cur : Option<rc::Rc<cell::RefCell<Node>>>
}
impl Iterator for ListIter
{
type Item = isize;
fn next(&mut self) -> Option<Self::Item>
{
match self.cur.take()
{
None => None,
Some(current_node_refcell_rc) =>
{
let node_ref : cell::Ref<'_, Node> = current_node_refcell_rc.borrow();
let data : isize = node_ref.data;
match &node_ref.next
{
None => self.cur = None,
Some(next) => self.cur = Some(rc::Rc::clone(&next))
};
return Some(data);
}
}
}
}