crndm 0.1.0

Persistent Programming Library
use crndm::default::*;
use std::fmt::Display;

type P = BuddyAlloc;

struct StackItem<T: PSafe> {
    data: T,
    next: Option<Parc<StackItem<T>>>,
}

pub struct Stack<T: PSafe> {
    len: usize,
    head: Option<Parc<StackItem<T>>>,
}

impl<T: PSafe> Stack<T> {
    pub fn new() -> Self {
        Self { len: 0, head: None }
    }

    pub fn push(&mut self, data: T, j: &Journal) {
        self.head = Some(Parc::new(
            StackItem {
                data,
                next: self.head.pclone(j),
            },
            j,
        ));
        self.len += 1;
    }

    pub fn pop(&mut self, j: &Journal) -> Option<T>
    where
        T: PClone<P>,
    {
        if let Some(head) = &self.head {
            let d = head.data.pclone(j);
            self.head = head.next.pclone(j);
            self.len -= 1;
            Some(d)
        } else {
            None
        }
    }

    pub fn clear(&mut self) {
        self.head = None;
        self.len = 0;
    }

    pub fn len(&self) -> usize {
        self.len
    }

    pub fn print_top10(&self)
    where
        T: Display,
    {
        let mut curr = &self.head;
        for i in 0..10 {
            if let Some(c) = curr {
                print!("{:2>}: {}", i + 1, c.data);
                curr = &c.next;
            } else {
                break;
            }
        }
        println!(
            "----------------------------------------------------- Total: {}",
            self.len
        );
    }

    pub fn print_all(&self)
    where
        T: Display,
    {
        let mut curr = &self.head;
        for i in 0..self.len() {
            if let Some(c) = curr {
                print!("{:2>}: {}", i + 1, c.data);
                curr = &c.next;
            } else {
                break;
            }
        }
        println!(
            "----------------------------------------------------- Total: {}",
            self.len
        );
    }
}