use std::cell::RefCell;
use std::option::Option;
use std::rc::Rc;
#[derive(Debug, Clone)]
struct Double_Node {
val: i64,
next: Option<Rc<RefCell<Double_Node>>>,
prev: Option<Rc<RefCell<Double_Node>>>,
}
impl Double_Node {
fn new(val: i64) -> Rc<RefCell<Double_Node>> {
return Rc::new(RefCell::new(Double_Node {
val,
next: None,
prev: None,
}));
}
}
pub struct Double_LinkedList {
length: usize,
head: Option<Rc<RefCell<Double_Node>>>,
tail: Option<Rc<RefCell<Double_Node>>>,
}
impl Double_LinkedList {
pub fn new() -> Double_LinkedList {
return Double_LinkedList {
length: 0,
head: None,
tail: None,
};
}
pub fn append(&mut self, val: i64) {
let new_node = Double_Node::new(val);
if self.length == 0 {
self.head = Some(new_node.clone());
self.tail = Some(new_node.clone());
} else {
let tail = self.tail.take().unwrap(); tail.borrow_mut().next = Some(new_node.clone()); new_node.borrow_mut().prev = Some(tail.clone());
self.tail = Some(new_node.clone());
}
self.length += 1;
}
pub fn pop(&mut self) -> Option<i64> {
let tail = self.tail.take();
let mut result = None;
match tail{
Some(node)=>{
result = Some(node.borrow().val);
self.tail = node.borrow().prev.clone();
match self.tail.as_ref(){
Some(tail)=>{
tail.borrow_mut().next=None;
}
None=>{
self.head = None;
}
}
}
None => {
return None;
}
}
result
}
pub fn iter(&self) -> Double_LinkedList_Iterator {
return Double_LinkedList_Iterator::new(self.head.clone());
}
}
pub struct Double_LinkedList_Iterator {
current: Option<Rc<RefCell<Double_Node>>>,
}
impl Double_LinkedList_Iterator {
fn new(current: Option<Rc<RefCell<Double_Node>>>) -> Double_LinkedList_Iterator {
return Double_LinkedList_Iterator { current };
}
}
impl Iterator for Double_LinkedList_Iterator {
type Item = i64;
fn next(&mut self) -> Option<i64> {
let mut result = None;
self.current = match &self.current {
Some(current) => {
let current = current.borrow(); result = Some(current.val);
match current.next.as_ref() { Some(current) => Some(current.clone()),
None => None,
}
}
None => None,
};
result
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_double_node_new() {
let mut test_double_node = Double_Node::new(10);
}
#[test]
fn test_double_linkedlist_iterator() {
let mut test = Double_LinkedList::new();
test.append(10);
test.append(15);
test.append(19);
test.append(21);
for i in test.iter() {
print!("{:?}\n", i);
}
}
#[test]
fn test_double_linkedlist_pop(){
let mut test = Double_LinkedList::new();
test.append(10);
test.append(15);
test.append(19);
test.append(21);
test.pop();
test.pop();
test.pop();
for i in test.iter() {
print!("{:?}\n", i);
}
}
}