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::meaning::Meaning;
362    use crate::calc::undo::Undo;
363    use crate::calc::value::tests::{parse_ref, parse_refs};
364    use crate::core::stack::{BracketStyle, StackItem, ValueStack};
365    use crate::regex;
366    use pretty_assertions::assert_eq;
367
368    // PEEK SINGLE
369
370    #[test]
371    fn peek_single_returns_item_from_single_value() {
372        let expected_items = vec![
373            parse_item("1"),
374            parse_item("2"),
375            parse_series(vec!["3", "4", "5"]),
376            parse_item("6"),
377        ];
378        let stack = ValueStack::new(vec![
379            parse_item("1"),
380            parse_item("2"),
381            parse_series(vec!["3", "4", "5"]),
382            parse_item("6"),
383        ]);
384        assert_eq!(stack.peek_single().ok(), Some(parse_ref("6")));
385        assert_eq!(stack.items, expected_items);
386    }
387
388    #[test]
389    fn peek_single_returns_item_from_three_item_series() {
390        let expected_items = vec![
391            parse_item("1"),
392            parse_item("2"),
393            parse_series(vec!["3", "4", "5"]),
394        ];
395        let stack = ValueStack::new(vec![
396            parse_item("1"),
397            parse_item("2"),
398            parse_series(vec!["3", "4", "5"]),
399        ]);
400        assert_eq!(stack.peek_single().ok(), Some(parse_ref("5")));
401        assert_eq!(stack.items, expected_items);
402    }
403
404    #[test]
405    fn peek_single_returns_item_from_two_item_series() {
406        let expected_items = vec![
407            parse_item("1"),
408            parse_item("2"),
409            parse_series(vec!["3", "4"]),
410        ];
411        let stack = ValueStack::new(vec![
412            parse_item("1"),
413            parse_item("2"),
414            parse_series(vec!["3", "4"]),
415        ]);
416        assert_eq!(stack.peek_single().ok(), Some(parse_ref("4")));
417        assert_eq!(stack.items, expected_items);
418    }
419
420    #[test]
421    fn peek_single_returns_item_from_one_item_series() {
422        // We should never have a one item series on the stack.
423        let expected_items = vec![
424            parse_item("1"),
425            parse_item("2"),
426            parse_series(vec!["3"]),
427        ];
428        let stack = ValueStack::new(vec![
429            parse_item("1"),
430            parse_item("2"),
431            parse_series(vec!["3"]),
432        ]);
433        assert_eq!(stack.peek_single().ok(), Some(parse_ref("3")));
434        assert_eq!(stack.items, expected_items);
435    }
436
437    #[test]
438    fn peek_single_returns_error_if_empty_series() {
439        // We should never have an empty series on the stack.
440        let expected_items = vec![
441            parse_item("1"),
442            parse_item("2"),
443            parse_series(vec![]),
444        ];
445        let stack = ValueStack::new(vec![
446            parse_item("1"),
447            parse_item("2"),
448            parse_series(vec![]),
449        ]);
450        assert_eq!(stack.peek_single().ok(), None);
451        assert_eq!(stack.items, expected_items);
452    }
453
454    #[test]
455    fn peek_single_returns_error_if_empty_stack() {
456        let expected_items: Vec<StackItem> = vec![];
457        let stack = ValueStack::new(vec![]);
458        assert_eq!(stack.peek_single().ok(), None);
459        assert_eq!(stack.items, expected_items);
460    }
461
462    // POP SINGLE
463
464    #[test]
465    fn pop_single_returns_item_from_single_value() {
466        let expected_items = vec![
467            parse_item("1"),
468            parse_item("2"),
469            parse_series(vec!["3", "4", "5"]),
470        ];
471        let expected_undo = Undo::new(0, vec![
472            parse_item("6"),
473        ], vec![]);
474        let mut stack = ValueStack::new(vec![
475            parse_item("1"),
476            parse_item("2"),
477            parse_series(vec!["3", "4", "5"]),
478            parse_item("6"),
479        ]);
480        let mut undo = Undo::new(0, vec![], vec![]);
481        assert_eq!(stack.pop_single(&mut undo, None).ok(), Some(parse_ref("6")));
482        assert_eq!(stack.items, expected_items);
483        assert_eq!(undo, expected_undo);
484    }
485
486    #[test]
487    fn pop_single_returns_item_from_three_item_series() {
488        let expected_items = vec![
489            parse_item("1"),
490            parse_item("2"),
491            parse_series(vec!["3", "4"]),
492        ];
493        let expected_undo = Undo::new(1, vec![
494            parse_series(vec!["3", "4", "5"]),
495        ], vec![]);
496        let mut stack = ValueStack::new(vec![
497            parse_item("1"),
498            parse_item("2"),
499            parse_series(vec!["3", "4", "5"]),
500        ]);
501        let mut undo = Undo::new(0, vec![], vec![]);
502        assert_eq!(stack.pop_single(&mut undo, None).ok(), Some(parse_ref("5")));
503        assert_eq!(stack.items, expected_items);
504        assert_eq!(undo, expected_undo);
505    }
506
507    #[test]
508    fn pop_single_returns_item_from_two_item_series() {
509        let expected_items = vec![
510            parse_item("1"),
511            parse_item("2"),
512            parse_item("3"),
513        ];
514        let expected_undo = Undo::new(1, vec![
515            parse_series(vec!["3", "4"]),
516        ], vec![]);
517        let mut stack = ValueStack::new(vec![
518            parse_item("1"),
519            parse_item("2"),
520            parse_series(vec!["3", "4"]),
521        ]);
522        let mut undo = Undo::new(0, vec![], vec![]);
523        assert_eq!(stack.pop_single(&mut undo, None).ok(), Some(parse_ref("4")));
524        assert_eq!(stack.items, expected_items);
525        assert_eq!(undo, expected_undo);
526    }
527
528    #[test]
529    fn pop_single_returns_item_from_one_item_series() {
530        // We should never have a one item series on the stack.
531        let expected_items = vec![
532            parse_item("1"),
533            parse_item("2"),
534        ];
535        let expected_undo = Undo::new(0, vec![
536            parse_series(vec!["3"]),
537        ], vec![]);
538        let mut stack = ValueStack::new(vec![
539            parse_item("1"),
540            parse_item("2"),
541            parse_series(vec!["3"]),
542        ]);
543        let mut undo = Undo::new(0, vec![], vec![]);
544        assert_eq!(stack.pop_single(&mut undo, None).ok(), Some(parse_ref("3")));
545        assert_eq!(stack.items, expected_items);
546        assert_eq!(undo, expected_undo);
547    }
548
549    #[test]
550    fn pop_single_returns_error_if_empty_series() {
551        // We should never have an empty series on the stack.
552        let expected_items = vec![
553            parse_item("1"),
554            parse_item("2"),
555        ];
556        let expected_undo = Undo::new(0, vec![], vec![]);
557        let mut stack = ValueStack::new(vec![
558            parse_item("1"),
559            parse_item("2"),
560            parse_series(vec![]),
561        ]);
562        let mut undo = Undo::new(0, vec![], vec![]);
563        assert_eq!(stack.pop_single(&mut undo, None).ok(), None);
564        assert_eq!(stack.items, expected_items);
565        assert_eq!(undo, expected_undo);
566    }
567
568    #[test]
569    fn pop_single_returns_error_if_empty_stack() {
570        let expected_items: Vec<StackItem> = vec![];
571        let expected_undo = Undo::new(0, vec![], vec![]);
572        let mut stack = ValueStack::new(vec![]);
573        let mut undo = Undo::new(0, vec![], vec![]);
574        assert_eq!(stack.pop_single(&mut undo, None).ok(), None);
575        assert_eq!(stack.items, expected_items);
576        assert_eq!(undo, expected_undo);
577    }
578
579    // POP MULTIPLE
580
581    #[test]
582    fn pop_multiple_returns_items_from_entire_stack() {
583        let expected_values = parse_refs(vec!["1", "2", "3", "4", "5", "6"]);
584        let expected_items = vec![];
585        let expected_undo = Undo::new(0, vec![
586            parse_item("1"),
587            parse_item("2"),
588            parse_series(vec!["3", "4", "5"]),
589            parse_item("6"),
590        ], vec![]);
591        let mut stack = ValueStack::new(vec![
592            parse_item("1"),
593            parse_item("2"),
594            parse_series(vec!["3", "4", "5"]),
595            parse_item("6"),
596        ]);
597        let mut undo = Undo::new(0, vec![], vec![]);
598        assert_eq!(stack.pop_series(&mut undo, None), (expected_values, false));
599        assert_eq!(stack.items, expected_items);
600        assert_eq!(undo, expected_undo);
601    }
602
603    #[test]
604    fn pop_multiple_returns_items_from_latest_series() {
605        let expected_values = parse_refs(vec!["3", "4", "5"]);
606        let expected_items = vec![
607            parse_item("1"),
608            parse_item("2"),
609        ];
610        let expected_undo = Undo::new(0, vec![
611            parse_series(vec!["3", "4", "5"]),
612        ], vec![]);
613        let mut stack = ValueStack::new(vec![
614            parse_item("1"),
615            parse_item("2"),
616            parse_series(vec!["3", "4", "5"]),
617        ]);
618        let mut undo = Undo::new(0, vec![], vec![]);
619        assert_eq!(stack.pop_series(&mut undo, None), (expected_values, true));
620        assert_eq!(stack.items, expected_items);
621        assert_eq!(undo, expected_undo);
622    }
623
624    // ITER MULTIPLE
625
626    #[test]
627    fn iter_multiple_returns_flattened_forward_items() {
628        let stack = ValueStack::new(vec![
629            parse_item("1"),
630            parse_item("2"),
631            parse_series(vec!["3", "4", "5"]),
632            parse_item("6"),
633        ]);
634        let mut iter = stack.iter_stack();
635        assert_eq!(iter.next(), Some((parse_ref("1"), BracketStyle::None)));
636        assert_eq!(iter.next(), Some((parse_ref("2"), BracketStyle::None)));
637        assert_eq!(iter.next(), Some((parse_ref("3"), BracketStyle::Open)));
638        assert_eq!(iter.next(), Some((parse_ref("4"), BracketStyle::Middle)));
639        assert_eq!(iter.next(), Some((parse_ref("5"), BracketStyle::Close)));
640        assert_eq!(iter.next(), Some((parse_ref("6"), BracketStyle::None)));
641        assert_eq!(iter.next(), None);
642    }
643
644    #[test]
645    fn iter_multiple_returns_flattened_backward_items() {
646        let stack = ValueStack::new(vec![
647            parse_item("1"),
648            parse_item("2"),
649            parse_series(vec!["3", "4", "5"]),
650            parse_item("6"),
651        ]);
652        let mut iter = stack.iter_stack();
653        assert_eq!(iter.next_back(), Some((parse_ref("6"), BracketStyle::None)));
654        assert_eq!(iter.next_back(), Some((parse_ref("5"), BracketStyle::Close)));
655        assert_eq!(iter.next_back(), Some((parse_ref("4"), BracketStyle::Middle)));
656        assert_eq!(iter.next_back(), Some((parse_ref("3"), BracketStyle::Open)));
657        assert_eq!(iter.next_back(), Some((parse_ref("2"), BracketStyle::None)));
658        assert_eq!(iter.next_back(), Some((parse_ref("1"), BracketStyle::None)));
659        assert_eq!(iter.next_back(), None);
660    }
661
662    // PUSH SINGLE
663
664    #[test]
665    fn push_single_appends_item_as_value() {
666        let expected_items = vec![
667            parse_item("1"),
668        ];
669        let expected_undo = Undo::new(1, vec![], vec![]);
670        let mut stack = ValueStack::new(vec![]);
671        let mut undo = Undo::new(0, vec![], vec![]);
672        stack.push_single(&mut undo, parse_ref("1"), None);
673        assert_eq!(stack.items, expected_items);
674        assert_eq!(undo, expected_undo);
675    }
676
677    // PUSH MULTIPLE
678
679    #[test]
680    fn push_multiple_appends_zero_items_as_nothing() {
681        let expected_items = vec![];
682        let expected_undo = Undo::new(0, vec![], vec![]);
683        let mut stack = ValueStack::new(vec![]);
684        let mut undo = Undo::new(0, vec![], vec![]);
685        assert_eq!(stack.push_series(&mut undo, parse_refs(vec![]), None), false);
686        assert_eq!(stack.items, expected_items);
687        assert_eq!(undo, expected_undo);
688    }
689
690    #[test]
691    fn push_multiple_appends_one_item_as_single() {
692        let expected_items = vec![
693            parse_item("1"),
694        ];
695        let expected_undo = Undo::new(1, vec![], vec![]);
696        let mut stack = ValueStack::new(vec![]);
697        let mut undo = Undo::new(0, vec![], vec![]);
698        assert_eq!(stack.push_series(&mut undo, parse_refs(vec!["1"]), None), true);
699        assert_eq!(stack.items, expected_items);
700        assert_eq!(undo, expected_undo);
701    }
702
703    #[test]
704    fn push_multiple_appends_two_items_as_series() {
705        let expected_items = vec![
706            parse_series(vec!["1", "2"]),
707        ];
708        let expected_undo = Undo::new(1, vec![], vec![]);
709        let mut stack = ValueStack::new(vec![]);
710        let mut undo = Undo::new(0, vec![], vec![]);
711        assert_eq!(stack.push_series(&mut undo, parse_refs(vec!["1", "2"]), None), true);
712        assert_eq!(stack.items, expected_items);
713        assert_eq!(undo, expected_undo);
714    }
715
716    // WRAPPED TOTALS
717
718    #[test]
719    fn test_wrapped_create_moodifies_total_from_items() {
720        let stack = ValueStack::new(vec![
721            parse_item("0"),
722            parse_item("0"),
723            parse_series(vec!["0", "0", "0"]),
724        ]);
725        assert_eq!(stack.items.len(), 3);
726        assert_eq!(stack.total, 5);
727    }
728
729    #[test]
730    fn test_wrapped_push_modifies_total_from_value() {
731        let mut stack = ValueStack::new(vec![]);
732        stack.wrapped_push(parse_item("0"));
733        assert_eq!(stack.items.len(), 1);
734        assert_eq!(stack.total, 1);
735        stack.wrapped_push(parse_item("0"));
736        assert_eq!(stack.items.len(), 2);
737        assert_eq!(stack.total, 2);
738    }
739
740    #[test]
741    fn test_wrapped_push_modifies_total_from_series() {
742        let mut stack = ValueStack::new(vec![]);
743        stack.wrapped_push(parse_series(vec!["0", "0", "0"]));
744        assert_eq!(stack.items.len(), 1);
745        assert_eq!(stack.total, 3);
746        stack.wrapped_push(parse_series(vec!["0", "0"]));
747        assert_eq!(stack.items.len(), 2);
748        assert_eq!(stack.total, 5);
749    }
750
751    #[test]
752    fn test_wrapped_append_modifies_total_from_items() {
753        let mut stack = ValueStack::new(vec![]);
754        let mut items = vec![
755            parse_item("0"),
756            parse_item("0"),
757            parse_series(vec!["0", "0", "0"]),
758        ];
759        stack.wrapped_append(&mut items);
760        assert_eq!(stack.items.len(), 3);
761        assert_eq!(stack.total, 5);
762    }
763
764    #[test]
765    fn test_wrapped_pop_modifies_total_from_value() {
766        let mut stack = ValueStack::new(vec![
767            parse_item("0"),
768            parse_item("0"),
769            parse_series(vec!["0", "0", "0"]),
770            parse_item("0"),
771        ]);
772        stack.wrapped_pop();
773        assert_eq!(stack.items.len(), 3);
774        assert_eq!(stack.total, 5);
775    }
776
777    #[test]
778    fn test_wrapped_pop_modifies_total_from_series() {
779        let mut stack = ValueStack::new(vec![
780            parse_item("0"),
781            parse_item("0"),
782            parse_series(vec!["0", "0", "0"]),
783        ]);
784        stack.wrapped_pop();
785        assert_eq!(stack.items.len(), 2);
786        assert_eq!(stack.total, 2);
787    }
788
789    #[test]
790    fn test_wrapped_pop_leaves_total_if_empty() {
791        let mut stack = ValueStack::new(vec![]);
792        stack.wrapped_pop();
793        assert_eq!(stack.items.len(), 0);
794        assert_eq!(stack.total, 0);
795    }
796
797    #[test]
798    fn test_wrapped_drain_modifies_total_if_complete() {
799        let mut stack = ValueStack::new(vec![
800            parse_item("0"),
801            parse_item("0"),
802            parse_series(vec!["0", "0", "0"]),
803            parse_item("0"),
804        ]);
805        stack.wrapped_drain(..);
806        assert_eq!(stack.items.len(), 0);
807        assert_eq!(stack.total, 0);
808    }
809
810    #[test]
811    fn test_wrapped_drain_modifies_total_if_partial() {
812        let mut stack = ValueStack::new(vec![
813            parse_item("0"),
814            parse_item("0"),
815            parse_series(vec!["0", "0", "0"]),
816            parse_item("0"),
817        ]);
818        stack.wrapped_drain(2..);
819        assert_eq!(stack.items.len(), 2);
820        assert_eq!(stack.total, 2);
821    }
822
823    pub fn parse_item(number: &str) -> StackItem {
824        let bracket_regex = regex!(r"^\[(.*)\]");
825        let token_regex = regex!(r"\b(\S+)\b");
826        if let Some(numbers) = bracket_regex.find(number) {
827            let numbers = numbers.as_str();
828            let numbers = token_regex.find_iter(numbers).map(|x| x.as_str()).collect();
829            StackItem::Series(parse_refs(numbers))
830        } else {
831            StackItem::Single(parse_ref(number))
832        }
833    }
834
835    pub fn parse_items(numbers: Vec<&str>) -> Vec<StackItem> {
836        numbers.iter().map(|x| parse_item(x)).collect()
837    }
838
839    pub fn parse_series(numbers: Vec<&str>) -> StackItem {
840        StackItem::Series(parse_refs(numbers))
841    }
842
843    impl StackItem {
844        pub fn with_meaning(self, meaning: Meaning) -> Self {
845            if let Self::Single(value) = &self {
846                value.borrow_mut().set_meaning(meaning);
847            }
848            self
849        }
850
851        pub fn with_variable(self, variable: &str) -> Self {
852            if let Self::Single(value) = &self {
853                value.borrow_mut().set_variable(variable);
854            }
855            self
856        }
857
858        pub fn with_comment(self, comment: &str) -> Self {
859            if let Self::Single(value) = &self {
860                value.borrow_mut().set_comment(comment);
861            }
862            self
863        }
864    }
865}