rpn_cli/core/
stack.rs

1use crate::calc::undo::Undo;
2use crate::calc::value::ValueRef;
3use crate::error::{EngineError, MyError, MyResult};
4use std::ops::RangeBounds;
5use std::rc::Rc;
6use std::slice::Iter;
7use std::vec::Drain;
8
9#[derive(Debug, PartialEq)]
10pub enum StackItem {
11    Single(ValueRef),
12    Series(Vec<ValueRef>),
13}
14
15impl StackItem {
16    fn len(&self) -> usize {
17        match self {
18            Self::Single(_) => 1,
19            Self::Series(values) => values.len(),
20        }
21    }
22}
23
24pub struct ValueStack {
25    pub items: Vec<StackItem>,
26    pub total: usize,
27}
28
29impl ValueStack {
30    pub fn new(items: Vec<StackItem>) -> Self {
31        let total = items.iter().map(StackItem::len).sum();
32        Self { items, total }
33    }
34
35    pub fn peek_single(&self) -> MyResult<ValueRef> {
36        if let Some(item) = self.items.last() {
37            match item {
38                StackItem::Single(value) => {
39                    Ok(Rc::clone(value))
40                }
41                StackItem::Series(values) => {
42                    if let Some(value) = values.last() {
43                        Ok(Rc::clone(value))
44                    } else {
45                        Err(MyError::from(EngineError::MissingValue))
46                    }
47                }
48            }
49        } else {
50            Err(MyError::from(EngineError::MissingValue))
51        }
52    }
53
54    pub fn pop_single(
55        &mut self,
56        undo: &mut Undo,
57        keyword: Option<&str>,
58    ) -> MyResult<ValueRef> {
59        if let Some(item) = self.wrapped_pop() {
60            match item {
61                StackItem::Single(value) => {
62                    undo.merge(0, vec![StackItem::Single(Rc::clone(&value))], keyword);
63                    Ok(value)
64                }
65                StackItem::Series(mut values) => {
66                    match values.len() {
67                        0 => {
68                            Err(MyError::from(EngineError::MissingValue))
69                        }
70                        1 => {
71                            let cloned = values.clone();
72                            let result = values.pop().unwrap();
73                            undo.merge(0, vec![StackItem::Series(cloned)], None);
74                            Ok(result)
75                        }
76                        2 => {
77                            let cloned = values.clone();
78                            let result = values.pop().unwrap();
79                            let next = values.pop().unwrap();
80                            self.wrapped_push(StackItem::Single(next));
81                            undo.merge(1, vec![StackItem::Series(cloned)], None);
82                            Ok(result)
83                        }
84                        _ => {
85                            let cloned = values.clone();
86                            let result = values.pop().unwrap();
87                            self.wrapped_push(StackItem::Series(values));
88                            undo.merge(1, vec![StackItem::Series(cloned)], None);
89                            Ok(result)
90                        }
91                    }
92                }
93            }
94        } else {
95            Err(MyError::from(EngineError::MissingValue))
96        }
97    }
98
99    pub fn pop_double(
100        &mut self,
101        undo: &mut Undo,
102        keyword: Option<&str>,
103    ) -> MyResult<(ValueRef, ValueRef)> {
104        let value2 = self.pop_single(undo, None)?;
105        let value1 = self.pop_single(undo, keyword)?;
106        Ok((value1, value2))
107    }
108
109    pub fn pop_triple(
110        &mut self,
111        undo: &mut Undo,
112        keyword: Option<&str>,
113    ) -> MyResult<(ValueRef, ValueRef, ValueRef)> {
114        let value3 = self.pop_single(undo, None)?;
115        let value2 = self.pop_single(undo, None)?;
116        let value1 = self.pop_single(undo, keyword)?;
117        Ok((value1, value2, value3))
118    }
119
120    pub fn pop_series(
121        &mut self,
122        undo: &mut Undo,
123        keyword: Option<&str>,
124    ) -> (Vec<ValueRef>, bool) {
125        if let Some(StackItem::Series(_)) = self.items.last() {
126            if let Some(StackItem::Series(values)) = self.wrapped_pop() {
127                let cloned = values.clone();
128                undo.merge(0, vec![StackItem::Series(cloned)], keyword);
129                return (values, true);
130            }
131        }
132        let values = self.pop_stack(undo, keyword);
133        (values, false)
134    }
135
136    pub fn pop_stack(
137        &mut self,
138        undo: &mut Undo,
139        keyword: Option<&str>,
140    ) -> Vec<ValueRef> {
141        let values = self.iter_stack().map(|(x, _)| x).collect();
142        let moved = self.wrapped_drain(..).collect();
143        undo.merge(0, moved, keyword);
144        values
145    }
146
147    pub fn iter_stack(&self) -> StackIter {
148        StackIter::new(self.items.iter(), self.total)
149    }
150
151    pub fn push_single(
152        &mut self,
153        undo: &mut Undo,
154        value: ValueRef,
155        keyword: Option<&str>,
156    ) {
157        self.wrapped_push(StackItem::Single(value));
158        undo.merge(1, vec![], keyword);
159    }
160
161    pub fn push_singles(
162        &mut self,
163        undo: &mut Undo,
164        values: Vec<ValueRef>,
165        keyword: Option<&str>,
166    ) -> bool {
167        if !values.is_empty() {
168            for value in values {
169                self.push_single(undo, value, None);
170            }
171            undo.merge(0, vec![], keyword);
172            return true;
173        }
174        false
175    }
176
177    pub fn push_series(
178        &mut self,
179        undo: &mut Undo,
180        values: Vec<ValueRef>,
181        keyword: Option<&str>,
182    ) -> bool {
183        match values.len() {
184            0 => {
185                false
186            }
187            1 => {
188                let value = values.into_iter().next().unwrap_or_default();
189                self.wrapped_push(StackItem::Single(value));
190                undo.merge(1, vec![], keyword);
191                true
192            }
193            _ => {
194                self.wrapped_push(StackItem::Series(values));
195                undo.merge(1, vec![], keyword);
196                true
197            }
198        }
199    }
200
201    pub fn total_len(&self) -> usize {
202        self.total
203    }
204
205    pub fn wrapped_len(&self) -> usize {
206        self.items.len()
207    }
208
209    pub fn wrapped_push(&mut self, item: StackItem) {
210        self.total += item.len();
211        self.items.push(item)
212    }
213
214    pub fn wrapped_append(&mut self, items: &mut Vec<StackItem>) {
215        self.total += items.iter().map(StackItem::len).sum::<usize>();
216        self.items.append(items)
217    }
218
219    pub fn wrapped_pop(&mut self) -> Option<StackItem> {
220        if let Some(item) = self.items.pop() {
221            self.total -= item.len();
222            return Some(item);
223        }
224        None
225    }
226
227    pub fn wrapped_drain<R: RangeBounds<usize>>(&mut self, range: R) -> Drain<StackItem> {
228        let drained = self.items.drain(range);
229        for item in drained.as_ref() {
230            self.total -= item.len();
231        }
232        drained
233    }
234}
235
236#[derive(Clone, Copy, Debug, PartialEq)]
237pub enum BracketStyle {
238    None,
239    Open,
240    Middle,
241    Close,
242}
243
244pub struct BracketChars {
245    pub open: (char, char),
246    pub middle: (char, char),
247    pub close: (char, char),
248}
249
250impl BracketChars {
251    pub fn get_prefix(&self, style: BracketStyle) -> Option<char> {
252        match style {
253            BracketStyle::None => None,
254            BracketStyle::Open => Some(self.open.0),
255            BracketStyle::Middle => Some(self.middle.0),
256            BracketStyle::Close => Some(self.close.0),
257        }
258    }
259
260    pub fn get_suffix(&self, style: BracketStyle) -> Option<char> {
261        match style {
262            BracketStyle::None => None,
263            BracketStyle::Open => Some(self.open.1),
264            BracketStyle::Middle => Some(self.middle.1),
265            BracketStyle::Close => Some(self.close.1),
266        }
267    }
268}
269
270pub struct StackIter<'a> {
271    outer: Iter<'a, StackItem>,
272    inner: Option<Iter<'a, ValueRef>>,
273    index: usize,
274    subtotal: usize,
275    total: usize,
276}
277
278impl<'a> StackIter<'a> {
279    fn new(outer: Iter<'a, StackItem>, total: usize) -> Self {
280        Self { outer, inner: None, index: 0, subtotal: 0, total }
281    }
282
283    fn advance_index(&mut self, reverse: bool) -> BracketStyle {
284        self.index += 1;
285        if self.index == 1 {
286            if reverse { BracketStyle::Close } else { BracketStyle::Open }
287        } else if self.index < self.subtotal {
288            BracketStyle::Middle
289        } else {
290            if reverse { BracketStyle::Open } else { BracketStyle::Close }
291        }
292    }
293}
294
295// noinspection DuplicatedCode
296impl<'a> Iterator for StackIter<'a> {
297    type Item = (ValueRef, BracketStyle);
298
299    fn next(&mut self) -> Option<Self::Item> {
300        loop {
301            if let Some(inner) = &mut self.inner {
302                if let Some(value) = inner.next() {
303                    let style = self.advance_index(false);
304                    return Some((Rc::clone(value), style));
305                }
306                self.inner = None;
307            } else if let Some(item) = self.outer.next() {
308                match item {
309                    StackItem::Single(value) => {
310                        return Some((Rc::clone(value), BracketStyle::None));
311                    }
312                    StackItem::Series(values) => {
313                        self.inner = Some(values.iter());
314                        self.index = 0;
315                        self.subtotal = values.len();
316                    }
317                }
318            } else {
319                return None;
320            }
321        }
322    }
323}
324
325// noinspection DuplicatedCode
326impl<'a> DoubleEndedIterator for StackIter<'a> {
327    fn next_back(&mut self) -> Option<Self::Item> {
328        loop {
329            if let Some(inner) = &mut self.inner {
330                if let Some(value) = inner.next_back() {
331                    let style = self.advance_index(true);
332                    return Some((Rc::clone(value), style));
333                }
334                self.inner = None;
335            } else if let Some(item) = self.outer.next_back() {
336                match item {
337                    StackItem::Single(value) => {
338                        return Some((Rc::clone(value), BracketStyle::None));
339                    }
340                    StackItem::Series(values) => {
341                        self.inner = Some(values.iter());
342                        self.index = 0;
343                        self.subtotal = values.len();
344                    }
345                }
346            } else {
347                return None;
348            }
349        }
350    }
351}
352
353impl<'a> ExactSizeIterator for StackIter<'a> {
354    fn len(&self) -> usize {
355        self.total
356    }
357}
358
359#[cfg(test)]
360pub mod tests {
361    use crate::calc::undo::Undo;
362    use crate::calc::value::tests::{parse_value, parse_values};
363    use crate::core::stack::{BracketStyle, StackItem, ValueStack};
364    use crate::regex;
365    use pretty_assertions::assert_eq;
366
367    // PEEK SINGLE
368
369    #[test]
370    fn peek_single_returns_item_from_single_value() {
371        let expected_items = vec![
372            parse_item("1"),
373            parse_item("2"),
374            parse_series(vec!["3", "4", "5"]),
375            parse_item("6"),
376        ];
377        let stack = ValueStack::new(vec![
378            parse_item("1"),
379            parse_item("2"),
380            parse_series(vec!["3", "4", "5"]),
381            parse_item("6"),
382        ]);
383        assert_eq!(stack.peek_single().ok(), Some(parse_value("6")));
384        assert_eq!(stack.items, expected_items);
385    }
386
387    #[test]
388    fn peek_single_returns_item_from_three_item_series() {
389        let expected_items = vec![
390            parse_item("1"),
391            parse_item("2"),
392            parse_series(vec!["3", "4", "5"]),
393        ];
394        let stack = ValueStack::new(vec![
395            parse_item("1"),
396            parse_item("2"),
397            parse_series(vec!["3", "4", "5"]),
398        ]);
399        assert_eq!(stack.peek_single().ok(), Some(parse_value("5")));
400        assert_eq!(stack.items, expected_items);
401    }
402
403    #[test]
404    fn peek_single_returns_item_from_two_item_series() {
405        let expected_items = vec![
406            parse_item("1"),
407            parse_item("2"),
408            parse_series(vec!["3", "4"]),
409        ];
410        let stack = ValueStack::new(vec![
411            parse_item("1"),
412            parse_item("2"),
413            parse_series(vec!["3", "4"]),
414        ]);
415        assert_eq!(stack.peek_single().ok(), Some(parse_value("4")));
416        assert_eq!(stack.items, expected_items);
417    }
418
419    #[test]
420    fn peek_single_returns_item_from_one_item_series() {
421        // We should never have a one item series on the stack.
422        let expected_items = vec![
423            parse_item("1"),
424            parse_item("2"),
425            parse_series(vec!["3"]),
426        ];
427        let stack = ValueStack::new(vec![
428            parse_item("1"),
429            parse_item("2"),
430            parse_series(vec!["3"]),
431        ]);
432        assert_eq!(stack.peek_single().ok(), Some(parse_value("3")));
433        assert_eq!(stack.items, expected_items);
434    }
435
436    #[test]
437    fn peek_single_returns_error_if_empty_series() {
438        // We should never have an empty series on the stack.
439        let expected_items = vec![
440            parse_item("1"),
441            parse_item("2"),
442            parse_series(vec![]),
443        ];
444        let stack = ValueStack::new(vec![
445            parse_item("1"),
446            parse_item("2"),
447            parse_series(vec![]),
448        ]);
449        assert_eq!(stack.peek_single().ok(), None);
450        assert_eq!(stack.items, expected_items);
451    }
452
453    #[test]
454    fn peek_single_returns_error_if_empty_stack() {
455        let expected_items: Vec<StackItem> = vec![];
456        let stack = ValueStack::new(vec![]);
457        assert_eq!(stack.peek_single().ok(), None);
458        assert_eq!(stack.items, expected_items);
459    }
460
461    // POP SINGLE
462
463    #[test]
464    fn pop_single_returns_item_from_single_value() {
465        let expected_items = vec![
466            parse_item("1"),
467            parse_item("2"),
468            parse_series(vec!["3", "4", "5"]),
469        ];
470        let expected_undo = Undo::new(0, vec![
471            parse_item("6"),
472        ], vec![]);
473        let mut stack = ValueStack::new(vec![
474            parse_item("1"),
475            parse_item("2"),
476            parse_series(vec!["3", "4", "5"]),
477            parse_item("6"),
478        ]);
479        let mut undo = Undo::new(0, vec![], vec![]);
480        assert_eq!(stack.pop_single(&mut undo, None).ok(), Some(parse_value("6")));
481        assert_eq!(stack.items, expected_items);
482        assert_eq!(undo, expected_undo);
483    }
484
485    #[test]
486    fn pop_single_returns_item_from_three_item_series() {
487        let expected_items = vec![
488            parse_item("1"),
489            parse_item("2"),
490            parse_series(vec!["3", "4"]),
491        ];
492        let expected_undo = Undo::new(1, vec![
493            parse_series(vec!["3", "4", "5"]),
494        ], vec![]);
495        let mut stack = ValueStack::new(vec![
496            parse_item("1"),
497            parse_item("2"),
498            parse_series(vec!["3", "4", "5"]),
499        ]);
500        let mut undo = Undo::new(0, vec![], vec![]);
501        assert_eq!(stack.pop_single(&mut undo, None).ok(), Some(parse_value("5")));
502        assert_eq!(stack.items, expected_items);
503        assert_eq!(undo, expected_undo);
504    }
505
506    #[test]
507    fn pop_single_returns_item_from_two_item_series() {
508        let expected_items = vec![
509            parse_item("1"),
510            parse_item("2"),
511            parse_item("3"),
512        ];
513        let expected_undo = Undo::new(1, vec![
514            parse_series(vec!["3", "4"]),
515        ], vec![]);
516        let mut stack = ValueStack::new(vec![
517            parse_item("1"),
518            parse_item("2"),
519            parse_series(vec!["3", "4"]),
520        ]);
521        let mut undo = Undo::new(0, vec![], vec![]);
522        assert_eq!(stack.pop_single(&mut undo, None).ok(), Some(parse_value("4")));
523        assert_eq!(stack.items, expected_items);
524        assert_eq!(undo, expected_undo);
525    }
526
527    #[test]
528    fn pop_single_returns_item_from_one_item_series() {
529        // We should never have a one item series on the stack.
530        let expected_items = vec![
531            parse_item("1"),
532            parse_item("2"),
533        ];
534        let expected_undo = Undo::new(0, vec![
535            parse_series(vec!["3"]),
536        ], vec![]);
537        let mut stack = ValueStack::new(vec![
538            parse_item("1"),
539            parse_item("2"),
540            parse_series(vec!["3"]),
541        ]);
542        let mut undo = Undo::new(0, vec![], vec![]);
543        assert_eq!(stack.pop_single(&mut undo, None).ok(), Some(parse_value("3")));
544        assert_eq!(stack.items, expected_items);
545        assert_eq!(undo, expected_undo);
546    }
547
548    #[test]
549    fn pop_single_returns_error_if_empty_series() {
550        // We should never have an empty series on the stack.
551        let expected_items = vec![
552            parse_item("1"),
553            parse_item("2"),
554        ];
555        let expected_undo = Undo::new(0, vec![], vec![]);
556        let mut stack = ValueStack::new(vec![
557            parse_item("1"),
558            parse_item("2"),
559            parse_series(vec![]),
560        ]);
561        let mut undo = Undo::new(0, vec![], vec![]);
562        assert_eq!(stack.pop_single(&mut undo, None).ok(), None);
563        assert_eq!(stack.items, expected_items);
564        assert_eq!(undo, expected_undo);
565    }
566
567    #[test]
568    fn pop_single_returns_error_if_empty_stack() {
569        let expected_items: Vec<StackItem> = vec![];
570        let expected_undo = Undo::new(0, vec![], vec![]);
571        let mut stack = ValueStack::new(vec![]);
572        let mut undo = Undo::new(0, vec![], vec![]);
573        assert_eq!(stack.pop_single(&mut undo, None).ok(), None);
574        assert_eq!(stack.items, expected_items);
575        assert_eq!(undo, expected_undo);
576    }
577
578    // POP MULTIPLE
579
580    #[test]
581    fn pop_multiple_returns_items_from_entire_stack() {
582        let expected_values = parse_values(vec!["1", "2", "3", "4", "5", "6"]);
583        let expected_items = vec![];
584        let expected_undo = Undo::new(0, vec![
585            parse_item("1"),
586            parse_item("2"),
587            parse_series(vec!["3", "4", "5"]),
588            parse_item("6"),
589        ], vec![]);
590        let mut stack = ValueStack::new(vec![
591            parse_item("1"),
592            parse_item("2"),
593            parse_series(vec!["3", "4", "5"]),
594            parse_item("6"),
595        ]);
596        let mut undo = Undo::new(0, vec![], vec![]);
597        assert_eq!(stack.pop_series(&mut undo, None), (expected_values, false));
598        assert_eq!(stack.items, expected_items);
599        assert_eq!(undo, expected_undo);
600    }
601
602    #[test]
603    fn pop_multiple_returns_items_from_latest_series() {
604        let expected_values = parse_values(vec!["3", "4", "5"]);
605        let expected_items = vec![
606            parse_item("1"),
607            parse_item("2"),
608        ];
609        let expected_undo = Undo::new(0, vec![
610            parse_series(vec!["3", "4", "5"]),
611        ], vec![]);
612        let mut stack = ValueStack::new(vec![
613            parse_item("1"),
614            parse_item("2"),
615            parse_series(vec!["3", "4", "5"]),
616        ]);
617        let mut undo = Undo::new(0, vec![], vec![]);
618        assert_eq!(stack.pop_series(&mut undo, None), (expected_values, true));
619        assert_eq!(stack.items, expected_items);
620        assert_eq!(undo, expected_undo);
621    }
622
623    // ITER MULTIPLE
624
625    #[test]
626    fn iter_multiple_returns_flattened_forward_items() {
627        let stack = ValueStack::new(vec![
628            parse_item("1"),
629            parse_item("2"),
630            parse_series(vec!["3", "4", "5"]),
631            parse_item("6"),
632        ]);
633        let mut iter = stack.iter_stack();
634        assert_eq!(iter.next(), Some((parse_value("1"), BracketStyle::None)));
635        assert_eq!(iter.next(), Some((parse_value("2"), BracketStyle::None)));
636        assert_eq!(iter.next(), Some((parse_value("3"), BracketStyle::Open)));
637        assert_eq!(iter.next(), Some((parse_value("4"), BracketStyle::Middle)));
638        assert_eq!(iter.next(), Some((parse_value("5"), BracketStyle::Close)));
639        assert_eq!(iter.next(), Some((parse_value("6"), BracketStyle::None)));
640        assert_eq!(iter.next(), None);
641    }
642
643    #[test]
644    fn iter_multiple_returns_flattened_backward_items() {
645        let stack = ValueStack::new(vec![
646            parse_item("1"),
647            parse_item("2"),
648            parse_series(vec!["3", "4", "5"]),
649            parse_item("6"),
650        ]);
651        let mut iter = stack.iter_stack();
652        assert_eq!(iter.next_back(), Some((parse_value("6"), BracketStyle::None)));
653        assert_eq!(iter.next_back(), Some((parse_value("5"), BracketStyle::Close)));
654        assert_eq!(iter.next_back(), Some((parse_value("4"), BracketStyle::Middle)));
655        assert_eq!(iter.next_back(), Some((parse_value("3"), BracketStyle::Open)));
656        assert_eq!(iter.next_back(), Some((parse_value("2"), BracketStyle::None)));
657        assert_eq!(iter.next_back(), Some((parse_value("1"), BracketStyle::None)));
658        assert_eq!(iter.next_back(), None);
659    }
660
661    // PUSH SINGLE
662
663    #[test]
664    fn push_single_appends_item_as_value() {
665        let expected_items = vec![
666            parse_item("1"),
667        ];
668        let expected_undo = Undo::new(1, vec![], vec![]);
669        let mut stack = ValueStack::new(vec![]);
670        let mut undo = Undo::new(0, vec![], vec![]);
671        stack.push_single(&mut undo, parse_value("1"), None);
672        assert_eq!(stack.items, expected_items);
673        assert_eq!(undo, expected_undo);
674    }
675
676    // PUSH MULTIPLE
677
678    #[test]
679    fn push_multiple_appends_zero_items_as_nothing() {
680        let expected_items = vec![];
681        let expected_undo = Undo::new(0, vec![], vec![]);
682        let mut stack = ValueStack::new(vec![]);
683        let mut undo = Undo::new(0, vec![], vec![]);
684        assert_eq!(stack.push_series(&mut undo, parse_values(vec![]), None), false);
685        assert_eq!(stack.items, expected_items);
686        assert_eq!(undo, expected_undo);
687    }
688
689    #[test]
690    fn push_multiple_appends_one_item_as_single() {
691        let expected_items = vec![
692            parse_item("1"),
693        ];
694        let expected_undo = Undo::new(1, vec![], vec![]);
695        let mut stack = ValueStack::new(vec![]);
696        let mut undo = Undo::new(0, vec![], vec![]);
697        assert_eq!(stack.push_series(&mut undo, parse_values(vec!["1"]), None), true);
698        assert_eq!(stack.items, expected_items);
699        assert_eq!(undo, expected_undo);
700    }
701
702    #[test]
703    fn push_multiple_appends_two_items_as_series() {
704        let expected_items = vec![
705            parse_series(vec!["1", "2"]),
706        ];
707        let expected_undo = Undo::new(1, vec![], vec![]);
708        let mut stack = ValueStack::new(vec![]);
709        let mut undo = Undo::new(0, vec![], vec![]);
710        assert_eq!(stack.push_series(&mut undo, parse_values(vec!["1", "2"]), None), true);
711        assert_eq!(stack.items, expected_items);
712        assert_eq!(undo, expected_undo);
713    }
714
715    // WRAPPED TOTALS
716
717    #[test]
718    fn test_wrapped_create_moodifies_total_from_items() {
719        let stack = ValueStack::new(vec![
720            parse_item("0"),
721            parse_item("0"),
722            parse_series(vec!["0", "0", "0"]),
723        ]);
724        assert_eq!(stack.items.len(), 3);
725        assert_eq!(stack.total, 5);
726    }
727
728    #[test]
729    fn test_wrapped_push_modifies_total_from_value() {
730        let mut stack = ValueStack::new(vec![]);
731        stack.wrapped_push(parse_item("0"));
732        assert_eq!(stack.items.len(), 1);
733        assert_eq!(stack.total, 1);
734        stack.wrapped_push(parse_item("0"));
735        assert_eq!(stack.items.len(), 2);
736        assert_eq!(stack.total, 2);
737    }
738
739    #[test]
740    fn test_wrapped_push_modifies_total_from_series() {
741        let mut stack = ValueStack::new(vec![]);
742        stack.wrapped_push(parse_series(vec!["0", "0", "0"]));
743        assert_eq!(stack.items.len(), 1);
744        assert_eq!(stack.total, 3);
745        stack.wrapped_push(parse_series(vec!["0", "0"]));
746        assert_eq!(stack.items.len(), 2);
747        assert_eq!(stack.total, 5);
748    }
749
750    #[test]
751    fn test_wrapped_append_modifies_total_from_items() {
752        let mut stack = ValueStack::new(vec![]);
753        let mut items = vec![
754            parse_item("0"),
755            parse_item("0"),
756            parse_series(vec!["0", "0", "0"]),
757        ];
758        stack.wrapped_append(&mut items);
759        assert_eq!(stack.items.len(), 3);
760        assert_eq!(stack.total, 5);
761    }
762
763    #[test]
764    fn test_wrapped_pop_modifies_total_from_value() {
765        let mut stack = ValueStack::new(vec![
766            parse_item("0"),
767            parse_item("0"),
768            parse_series(vec!["0", "0", "0"]),
769            parse_item("0"),
770        ]);
771        stack.wrapped_pop();
772        assert_eq!(stack.items.len(), 3);
773        assert_eq!(stack.total, 5);
774    }
775
776    #[test]
777    fn test_wrapped_pop_modifies_total_from_series() {
778        let mut stack = ValueStack::new(vec![
779            parse_item("0"),
780            parse_item("0"),
781            parse_series(vec!["0", "0", "0"]),
782        ]);
783        stack.wrapped_pop();
784        assert_eq!(stack.items.len(), 2);
785        assert_eq!(stack.total, 2);
786    }
787
788    #[test]
789    fn test_wrapped_pop_leaves_total_if_empty() {
790        let mut stack = ValueStack::new(vec![]);
791        stack.wrapped_pop();
792        assert_eq!(stack.items.len(), 0);
793        assert_eq!(stack.total, 0);
794    }
795
796    #[test]
797    fn test_wrapped_drain_modifies_total_if_complete() {
798        let mut stack = ValueStack::new(vec![
799            parse_item("0"),
800            parse_item("0"),
801            parse_series(vec!["0", "0", "0"]),
802            parse_item("0"),
803        ]);
804        stack.wrapped_drain(..);
805        assert_eq!(stack.items.len(), 0);
806        assert_eq!(stack.total, 0);
807    }
808
809    #[test]
810    fn test_wrapped_drain_modifies_total_if_partial() {
811        let mut stack = ValueStack::new(vec![
812            parse_item("0"),
813            parse_item("0"),
814            parse_series(vec!["0", "0", "0"]),
815            parse_item("0"),
816        ]);
817        stack.wrapped_drain(2..);
818        assert_eq!(stack.items.len(), 2);
819        assert_eq!(stack.total, 2);
820    }
821
822    pub fn parse_item(number: &str) -> StackItem {
823        let bracket_regex = regex!(r"^\[(.*)\]");
824        let token_regex = regex!(r"\b(\S+)\b");
825        if let Some(numbers) = bracket_regex.find(number) {
826            let numbers = numbers.as_str();
827            let numbers = token_regex.find_iter(numbers).map(|x| x.as_str()).collect();
828            StackItem::Series(parse_values(numbers))
829        } else {
830            StackItem::Single(parse_value(number))
831        }
832    }
833
834    pub fn parse_items(numbers: Vec<&str>) -> Vec<StackItem> {
835        numbers.iter().map(|x| parse_item(x)).collect()
836    }
837
838    pub fn parse_series(numbers: Vec<&str>) -> StackItem {
839        StackItem::Series(parse_values(numbers))
840    }
841}