use std::{
    borrow::BorrowMut,
    cell::{RefCell, RefMut},
    ops::Deref,
    rc::Rc,
};
struct Node {
    val: u32,
    next: Option<Rc<RefCell<Node>>>,
}
struct SingleList {
    head: Option<Rc<RefCell<Node>>>,
    tail: Option<Rc<RefCell<Node>>>,
}
impl SingleList {
    fn new() -> Self {
        SingleList {
            head: None,
            tail: None,
        }
    }
    fn display(&self) {
        let mut current = self.head.clone();
        while let Some(node) = current {
            let val = node.borrow().val;
            println!("{}", val);
            current = node.borrow().next.clone();
        }
    }
    fn append(&mut self, x: u32) {
        let newNode = Option::Some(Rc::new(RefCell::new(Node { val: x, next: None })));
        if let None = self.tail {
            self.tail = newNode;
            self.head = Some(self.tail.as_ref().unwrap().clone());
            return;
        }
        let tt = self.tail.take();
        let mut nx = tt.as_ref().unwrap().deref().borrow_mut();
        (*nx).next = Some(newNode.as_ref().unwrap().clone());
        self.tail = newNode;
    }
    fn pop(&mut self) {
        let mut head = self.head.clone();
        let mut last: Option<Rc<RefCell<Node>>> = None;
        loop {
            let before_take = head.clone();
            let temp = head.take();
            let mut next = temp.unwrap().borrow().next.clone();
            if let None = next {
                if let None = last {
                    self.head = None;
                    self.tail = None;
                    break;
                }
                last.as_ref().unwrap().deref().borrow_mut().next = None;
                break;
            }
            let t = next.take();
            last = before_take;
            head = t;
        }
    }
}

fn main() {
    let a = &mut SingleList::new();
    a.append(1);
    a.append(2);
    a.append(3);
    a.append(4);
    a.pop();
    a.display();
}