1use std::fmt;
2
3#[derive(Clone, Debug)]
4pub struct PushStack<T> {
5 elements: Vec<T>,
6}
7
8pub trait PushPrint {
9 fn to_pstring(&self) -> String;
10}
11
12impl PushPrint for f32 {
13 fn to_pstring(&self) -> String {
14 format!("{:.1}", self)
15 }
16}
17
18impl PushPrint for i32 {
19 fn to_pstring(&self) -> String {
20 self.to_string()
21 }
22}
23
24impl PushPrint for String {
25 fn to_pstring(&self) -> String {
26 self.to_string()
27 }
28}
29
30impl PushPrint for bool {
31 fn to_pstring(&self) -> String {
32 format!("{}", self.to_string().to_uppercase())
33 }
34}
35
36impl<T> PushStack<T>
37where
38 T: Clone + fmt::Display + PartialEq + PushPrint,
39{
40 pub fn new() -> Self {
41 Self {
42 elements: Vec::new(),
43 }
44 }
45
46 pub fn from_vec(elements: Vec<T>) -> Self {
49 Self { elements: elements }
50 }
51
52 pub fn to_string(&self) -> String {
54 let mut result = "".to_string();
55 for (_i, x) in self.elements.iter().rev().enumerate() {
56 result.push_str(&format!(" {}", x.to_pstring()));
57 }
58 result.trim().to_string()
59 }
60
61 pub fn size(&self) -> usize {
63 return self.elements.len();
64 }
65
66 pub fn last_eq(&self, item: &T) -> bool {
70 return Some(item) == self.elements.last();
71 }
72
73 pub fn equal_at(&self, i: usize, el: &T) -> Option<bool> {
77 if i > self.size() {
78 None
79 } else {
80 Some(self.elements[self.size() - (i + 1)].to_string() == *el.to_string())
81 }
82 }
83
84 pub fn bottom_mut(&mut self) -> Option<&mut T> {
87 if self.size() > 0 {
88 self.elements.first_mut()
89 } else {
90 None
91 }
92 }
93
94 pub fn flush(&mut self) {
96 self.elements = Vec::new();
97 }
98
99 pub fn replace(&mut self, i: usize, new_el: T) -> Result<(), usize> {
102 let size = &mut self.size();
103 match i.checked_sub(*size) {
104 None => {
105 let _ = std::mem::replace(&mut self.elements[*size - (i + 1)], new_el);
106 Ok(())
107 }
108 Some(diff) => Err(diff + 1),
109 }
110 }
111
112 pub fn remove(&mut self, i: usize) {
114 let size = self.size();
115 if i < size {
116 self.elements.remove(size - (i + 1));
117 }
118 }
119
120 pub fn reverse(&mut self) {
122 self.elements.reverse();
123 }
124
125 pub fn get_mut(&mut self, i: usize) -> Option<&mut T> {
128 let size = &mut self.size();
129 if i < *size {
130 Some(&mut self.elements[*size - (i + 1)])
131 } else {
132 None
133 }
134 }
135
136 pub fn get(&self, i: usize) -> Option<&T> {
139 let size = self.size();
140 if i < size {
141 Some(&self.elements[size - (i + 1)])
142 } else {
143 None
144 }
145 }
146
147 pub fn push(&mut self, value: T) {
149 self.elements.push(value);
150 }
151
152 pub fn push_front(&mut self, value: T) {
154 self.elements.insert(0, value);
155 }
156
157 pub fn yank(&mut self, index: usize) {
160 if index > 0 && index < self.size() {
161 let el = self.elements.remove(self.size() - (index + 1));
162 self.elements.push(el);
163 }
164 }
165
166 pub fn shove(&mut self, index: usize) {
169 if index > 0 && index < self.size() {
170 if let Some(el) = self.elements.pop() {
171 let top_down_index = self.size() - index;
172 self.elements.insert(top_down_index, el);
173 }
174 }
175 }
176
177 pub fn swap(&mut self, i: usize, j: usize) {
179 self.elements.swap(i, j);
180 }
181
182 pub fn pop_front(&mut self) -> Option<T> {
184 if self.elements.is_empty() {
185 return None;
186 }
187 Some(self.elements.remove(0))
188 }
189
190 pub fn pop(&mut self) -> Option<T> {
192 self.elements.pop()
193 }
194
195 pub fn pop_vec(&mut self, n: usize) -> Option<Vec<T>> {
199 if n > self.elements.len() {
200 None
201 } else {
202 Some(
203 self.elements
204 .split_off(self.elements.len() - n)
205 .into_iter()
206 .collect(),
207 )
208 }
209 }
210
211 pub fn copy(&self, i: usize) -> Option<T> {
214 if self.size() == 0 || i > self.size() - 1 {
215 None
216 } else {
217 Some(self.elements[self.size() - (i + 1)].clone())
218 }
219 }
220
221 pub fn copy_vec(&self, n: usize) -> Option<Vec<T>> {
225 if n > self.size() {
226 None
227 } else {
228 let mut cpy = Vec::with_capacity(n);
229 for i in 0..n {
230 cpy.push(self.elements[self.size() - n + i].clone());
231 }
232 Some(cpy)
233 }
234 }
235
236 pub fn push_vec(&mut self, to_push: Vec<T>) {
239 self.elements.extend(to_push);
240 }
241}
242
243#[cfg(test)]
244mod tests {
245 use super::*;
246
247 #[test]
248 fn pop_vec_in_right_order() {
249 let mut test_stack = PushStack {
250 elements: vec![1, 2, 3],
251 };
252
253 match test_stack.pop_vec(2) {
254 None => assert!(false),
255 Some(pv) => assert_eq!(pv[0], 2),
256 }
257 }
258
259 #[test]
260 fn pop_vec_max_index() {
261 let mut test_stack = PushStack {
262 elements: vec![1, 2, 3],
263 };
264 match test_stack.pop_vec(4) {
265 None => assert!(true),
266 Some(_pv) => assert!(false),
267 }
268 }
269
270 #[test]
271 fn push_vec_in_right_order() {
272 let mut test_stack = PushStack {
273 elements: vec![1, 2, 3],
274 };
275 let test_vec = vec![4, 5];
276 test_stack.push_vec(test_vec);
277 assert_eq!(test_stack.elements, [1, 2, 3, 4, 5]);
278 }
279
280 #[test]
281 fn copy_vec_preserves_stack() {
282 let test_stack = PushStack {
283 elements: vec![1, 2, 3],
284 };
285
286 match test_stack.copy_vec(2) {
287 None => assert!(false, "Should return values"),
288 Some(cv) => {
289 assert_eq!(cv.len(), 2);
290 assert_eq!(cv[0], 2);
291 assert_eq!(cv[1], 3);
292 }
293 }
294 assert_eq!(
295 test_stack.elements.len(),
296 3,
297 "Test stack should remain the same"
298 )
299 }
300
301 #[test]
302 fn equal_at_checks_equality_at_right_index() {
303 let test_stack = PushStack {
304 elements: vec![1, 2, 3, 4, 5],
305 };
306 assert_eq!(test_stack.equal_at(0, &5), Some(true));
307 assert_eq!(test_stack.equal_at(3, &2), Some(true));
308 assert_eq!(test_stack.equal_at(3, &1), Some(false));
309 }
310
311 #[test]
312 fn yank_vec_returns_right_order() {
313 let mut test_stack = PushStack {
314 elements: vec![1, 2, 3, 4, 5],
315 };
316 let mut test_idx = 1;
317 test_stack.yank(test_idx);
318 assert_eq!(test_stack.elements, [1, 2, 3, 5, 4]);
319 test_idx = 5; test_stack.yank(test_idx);
321 assert_eq!(test_stack.elements, [1, 2, 3, 5, 4]);
322 test_idx = 3;
323 test_stack.yank(test_idx);
324 assert_eq!(test_stack.elements, [1, 3, 5, 4, 2]);
325 test_idx = 0; test_stack.yank(test_idx);
327 assert_eq!(test_stack.elements, [1, 3, 5, 4, 2]);
328 }
329
330 #[test]
331 fn shove_vec_returns_right_order() {
332 let mut test_stack = PushStack {
333 elements: vec![1, 2, 3, 4, 5],
334 };
335 let mut test_idx = 1;
336 test_stack.shove(test_idx);
337 assert_eq!(test_stack.elements, [1, 2, 3, 5, 4]);
338 test_idx = 4; test_stack.shove(test_idx);
340 assert_eq!(test_stack.elements, [4, 1, 2, 3, 5]);
341 test_idx = 3;
342 test_stack.shove(test_idx);
343 assert_eq!(test_stack.elements, [4, 5, 1, 2, 3]);
344 test_idx = 0; test_stack.shove(test_idx);
346 assert_eq!(test_stack.elements, [4, 5, 1, 2, 3]);
347 }
348
349 #[test]
350 fn last_eq_preserves_vector() {
351 let test_stack = PushStack {
352 elements: vec![1, 2, 3, 4, 5],
353 };
354 let candidate = 5;
355 assert_eq!(test_stack.last_eq(&candidate), true);
356 let candidate = 4;
357 assert_eq!(test_stack.last_eq(&candidate), false);
358 assert_eq!(test_stack.size(), 5);
359 let test_stack = PushStack {
360 elements: Vec::new(),
361 };
362 assert_eq!(test_stack.last_eq(&candidate), false);
363 }
364
365 #[test]
366 fn replace_returns_right_offset() {
367 let mut test_stack = PushStack {
368 elements: vec![1, 2, 3, 4, 5],
369 };
370 assert_eq!(test_stack.replace(1, 19), Ok(()));
371 assert_eq!(test_stack.replace(5, 19), Err(1));
372 assert_eq!(test_stack.replace(6, 19), Err(2));
373 assert_eq!(test_stack.replace(4, 19), Ok(()));
374 assert_eq!(test_stack.replace(0, 19), Ok(()));
375 assert_eq!(test_stack.to_string(), "19 19 3 2 19");
376 }
377
378 #[test]
379 fn reverse_elements() {
380 let mut test_stack = PushStack {
381 elements: vec![1, 2, 3, 4, 5],
382 };
383 test_stack.reverse();
384 assert_eq!(test_stack.elements, [5, 4, 3, 2, 1]);
385 }
386}