Skip to content
Snippets Groups Projects
stack.rs 3.19 KiB
Newer Older
Annabella Gethke's avatar
Annabella Gethke committed
use crate::Stack;
unknown's avatar
unknown committed
use std::mem;
Annabella Gethke's avatar
Annabella Gethke committed
// TODO Complete implementation
impl Stack for Vec<i32> {
    fn init() -> Self {
unknown's avatar
unknown committed
            Vec::new()
Annabella Gethke's avatar
Annabella Gethke committed
    }

    fn push_val(&mut self, i: i32) {
unknown's avatar
unknown committed
        (*self).push(i);
Annabella Gethke's avatar
Annabella Gethke committed
    }

    fn top_val(&self) -> Option<&i32> {
unknown's avatar
unknown committed
        /*either dereference self or access last reference to last element and check if empty */
        if (*self).is_empty(){
            None
        }else{
            // returns reference of last element of vec
            Some(&self[self.len()-1])
        }

Annabella Gethke's avatar
Annabella Gethke committed
    }

    fn pop_val(&mut self) -> Option<i32> {
unknown's avatar
unknown committed
        if (*self).is_empty(){
            None
        }else{
            (*self).pop()
        }
Annabella Gethke's avatar
Annabella Gethke committed
    }

    fn is_empty(&self) -> bool {
unknown's avatar
unknown committed
        if (*self).is_empty(){
            return true;
        }else{
            return false;
        }
Annabella Gethke's avatar
Annabella Gethke committed
    }
}

#[derive(Debug)]
pub enum ListStack {
    Val(i32, Option<Box<ListStack>>),
    Nil,
}

use ListStack::Nil;
use ListStack::Val;

// Complete implementation of Stack for ListStack
impl Stack for ListStack {
    fn init() -> Self {
        Nil
    }

    fn push_val(&mut self, i: i32) {
unknown's avatar
unknown committed
        
Annabella Gethke's avatar
Annabella Gethke committed
        match self {
            //mem:replace notwendig da liststack keinen copytrait hat und wir so nicht ownership wechseln koennen             
unknown's avatar
unknown committed
            Val(value, other) => *self = Val(i,Some(Box::new(std::mem::replace(self, Nil)))),
            //zeigt urspruenglich auf nil  => fuege ein und mache restliste zu nil
            Nil => *self = Val(i,None),
unknown's avatar
unknown committed

Annabella Gethke's avatar
Annabella Gethke committed
    fn top_val(&self) -> Option<&i32> {
unknown's avatar
unknown committed
            match self{
                Nil => None,
                Val(value, other) => Some(value),
        
            }

Annabella Gethke's avatar
Annabella Gethke committed
    }

    fn pop_val(&mut self) -> Option<i32> {
        match self {
            Val(value, other) => {
                let popped_value = *value;
                match other.take() {
                    None => *self = Nil,
unknown's avatar
unknown committed
                    //some(other) also findet die box<liststack> also box pointer/reference auf liststack. *other zum dereference
                    Some(other) => *self = *other ,
Annabella Gethke's avatar
Annabella Gethke committed
                };
unknown's avatar
unknown committed
                //gebe popped wert zurueck
                Some(popped_value)
Annabella Gethke's avatar
Annabella Gethke committed
            }
            Nil => None,
        }
    }

    fn is_empty(&self) -> bool {
unknown's avatar
unknown committed
        match self{
            Nil => true,
            Val(value,other) => false,
        }
Annabella Gethke's avatar
Annabella Gethke committed
    }
}

#[cfg(test)]
mod tests {
    use crate::stack::ListStack;
    use crate::Stack;
    use std::fmt::Debug;

    #[test]
    fn vec_fill_and_clear() {
        println! {"Testing Vec<T>"}
        fill_and_clear_impl(Vec::init());
    }

    #[test]
    fn linked_fill_and_clear() {
        println! {"Testing ListStack"}
        fill_and_clear_impl(ListStack::init());
    }

    fn fill_and_clear_impl<T: Stack + Debug>(mut stack: T) {
        stack.push_val(1);
        assert_eq!(stack.top_val(), Some(&1));

        stack.push_val(2);
        assert_eq!(stack.top_val(), Some(&2));

        stack.push_val(-3);
        assert_eq!(stack.top_val(), Some(&-3));

        println!("{:?}", stack);

        let mut comparison = vec![1, 2, -3];
        while let Some(val) = stack.pop_val() {
            assert_eq!(comparison.pop().unwrap(), val);
        }

        assert!(stack.is_empty())
unknown's avatar
unknown committed
    } 

}