1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
use alloc::vec::Vec;

/// # stack data structure
/// 在栈中,被删除的是最近插入的元素: 栈的实现是一种后进先出策略。
/// 这里采用数组实现栈,还有别的方式也是可以实现栈的。
///
/// ## 栈的操作
/// 栈的操作有,栈上的INSERT操作称为压入PUSH,而无元素参数的DELETE操作称为弹出POP。
#[derive(Debug)]
pub struct Stack<T> {
    // data
    data: Vec<T>,
    // the stack top pointer, just the vector dynomic length
    top: usize,
}

impl<T: Clone> Default for Stack<T> {
    fn default() -> Self {
        Self::new()
    }
}

impl<T: Clone> Stack<T> {
    /// Creating an empty stack
    ///
    /// ```rust
    /// use algorithms_rs::Stack;
    ///
    /// let stack = Stack::<i32>::new();
    ///
    /// assert_eq!(stack.is_empty(), true);
    /// ```
    pub fn new() -> Stack<T> {
        Self {
            data: Vec::new(),
            top: 0,
        }
    }

    /// Determine if stack is empty
    ///
    /// ```rust
    /// use algorithms_rs::Stack;
    ///
    /// let mut stack = Stack::<i32>::new();
    ///
    /// assert_eq!(stack.is_empty(), true);
    ///
    /// stack.push(2);
    ///
    /// assert_eq!(stack.is_empty(), false);
    /// ```
    /// ```no
    /// STACK-EMPTY(S)
    /// if S.top == 0
    ///     return true
    /// else return false
    /// ```
    pub fn is_empty(&self) -> bool {
        self.top == 0
    }

    /// Put an element into the top of the stack of stack
    ///
    /// ```rust
    /// use algorithms_rs::Stack;
    ///
    /// let mut stack = Stack::<i32>::new();
    ///
    /// stack.push(1);
    ///
    /// assert_eq!(stack.is_empty(), false);
    /// ```
    /// ```no
    /// PUSH(S, x)
    ///     S.top = S.top + 1
    ///     S[S.top] = x
    /// ```
    pub fn push(&mut self, element: T) {
        self.top += 1;
        self.data.push(element);
    }

    /// Remove an element from the top of the stack of stack
    ///
    /// ```rust
    /// use algorithms_rs::Stack;
    ///
    /// let mut stack = Stack::<i32>::new();
    ///
    /// stack.push(1);
    ///
    /// let element = stack.pop().unwrap();
    ///
    /// assert_eq!(element, 1);
    /// assert_eq!(stack.is_empty(), true);
    ///
    /// if let Err(err) = stack.pop() {
    ///  assert_eq!(err.to_string(), "underflow".to_string())
    /// }
    ///
    /// ```
    /// ```no
    /// POP(S)
    ///     if STACK-EMPTY(S)
    ///         error "underflow"
    ///     else
    ///         S.top = S.top - 1
    ///         return S[S.top + 1]
    /// ```
    pub fn pop(&mut self) -> anyhow::Result<T> {
        if self.is_empty() {
            Err(anyhow::anyhow!("underflow"))
        } else {
            self.top -= 1;
            Ok(self.data.remove(self.top))
        }
    }

    /// Return the top element of the stack
    ///
    /// ```rust
    /// use algorithms_rs::Stack;
    ///
    /// let mut stack = Stack::<i32>::new();
    ///
    /// assert_eq!(stack.peek(), None);
    ///
    /// stack.push(1);
    /// stack.push(2);
    ///
    /// assert_eq!(stack.peek(), Some(&2));
    /// assert_eq!(stack.is_empty(), false);
    /// ```
    pub fn peek(&self) -> Option<&T> {
        if self.is_empty() {
            return None;
        }
        self.data.get(self.top - 1)
    }

    /// the stack size
    /// ```rust
    /// use algorithms_rs::Stack;
    ///
    /// let stack = Stack::<i32>::new();
    ///
    /// assert_eq!(0, stack.size());
    /// ```
    pub fn size(&self) -> usize {
        self.top
    }
}