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
295impl<'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
325impl<'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 #[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 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 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 #[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 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 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 #[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 #[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 #[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 #[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 #[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}