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::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 #[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 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 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 #[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 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 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 #[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 #[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 #[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 #[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 #[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}