mexprp/
answer.rs

1use crate::num::Num;
2use crate::opers::Calculation;
3use std::fmt;
4
5/// An answer of an evaluatation. Can be either a single answer or multiple. This struct contains some
6/// helper methods for performing operations on single or multiple answers. The `op` method takes another
7/// `Num`, and a function with two `Num` arguments, itself and the other (as references). It performs
8/// that function on all combinations and returns an answer with all of the results in one. The `unop`
9/// function is similar but it performs an operation on only itself, without another value (*un*ary
10/// *op*eration).
11#[derive(Debug, Clone, PartialEq)]
12pub enum Answer<N: Num> {
13	/// A single answer
14	Single(N),
15	/// Multiple answers. Will always be at least two (probably)
16	Multiple(Vec<N>),
17}
18
19impl<N: Num> Answer<N> {
20	/// Perform an operation on all the values of an answer with all the values of another answer
21	pub fn op<F: Fn(&N, &N) -> Calculation<N>>(&self, other: &Self, oper: F) -> Calculation<N> {
22		fn push_answers<N: Num>(answer: Answer<N>, list: &mut Vec<N>) {
23			match answer {
24				Answer::Single(n) => list.push(n),
25				Answer::Multiple(ns) => for n in ns {
26					list.push(n)
27				},
28			}
29		}
30
31		match *self {
32			Answer::Single(ref n) => match *other {
33				Answer::Single(ref n2) => oper(n, n2),
34				Answer::Multiple(ref n2s) => {
35					let mut answers = Vec::new();
36					for n2 in n2s {
37						push_answers(oper(n, n2)?, &mut answers);
38					}
39					Ok(Answer::Multiple(answers))
40				}
41			},
42			Answer::Multiple(ref ns) => match *other {
43				Answer::Single(ref n2) => {
44					let mut answers = Vec::new();
45					for n in ns {
46						push_answers(oper(n, n2)?, &mut answers);
47					}
48					Ok(Answer::Multiple(answers))
49				}
50				Answer::Multiple(ref n2s) => {
51					let mut answers = Vec::new();
52					for n in ns {
53						for n2 in n2s {
54							push_answers(oper(n, n2)?, &mut answers);
55						}
56					}
57					Ok(Answer::Multiple(answers))
58				}
59			},
60		}
61	}
62
63	/// Perform an operation on all the values of an answer
64	pub fn unop<F: Fn(&N) -> Calculation<N>>(&self, oper: F) -> Calculation<N> {
65		fn push_answers<N: Num>(answer: Answer<N>, list: &mut Vec<N>) {
66			match answer {
67				Answer::Single(n) => list.push(n),
68				Answer::Multiple(ns) => for n in ns {
69					list.push(n)
70				},
71			}
72		}
73
74		match *self {
75			Answer::Single(ref n) => oper(n),
76			Answer::Multiple(ref ns) => {
77				let mut answers = Vec::new();
78				for n in ns {
79					push_answers(oper(n)?, &mut answers);
80				}
81				Ok(Answer::Multiple(answers))
82			}
83		}
84	}
85
86	/// Unwrap the single variant of an answer
87	pub fn unwrap_single(self) -> N {
88		match self {
89			Answer::Single(n) => n,
90			Answer::Multiple(_) => panic!("Attempted to unwrap multiple answers as one"),
91		}
92	}
93
94	/// Convert this answer into a vector
95	pub fn to_vec(self) -> Vec<N> {
96		match self {
97			Answer::Single(n) => vec![n],
98			Answer::Multiple(ns) => ns,
99		}
100	}
101
102	/// Adds all the answers of another answer to the asnwers of this answer, returning a new answer
103	pub fn join(self, other: Self) -> Self {
104		let mut new = Vec::new();
105		match self {
106			Answer::Single(n) => {
107				new.push(n);
108			}
109			Answer::Multiple(mut ns) => {
110				new.append(&mut ns);
111			}
112		}
113
114		match other {
115			Answer::Single(n) => {
116				new.push(n);
117			}
118			Answer::Multiple(mut ns) => {
119				new.append(&mut ns);
120			}
121		}
122		Answer::Multiple(new)
123	}
124}
125
126impl<N: Num> fmt::Display for Answer<N> {
127	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128		match *self {
129			Answer::Single(ref n) => write!(f, "{}", n),
130			Answer::Multiple(ref ns) => {
131				let mut buf = String::from("{");
132				for (i, n) in ns.iter().enumerate() {
133					buf.push_str(&format!("{}", n));
134					if i + 1 < ns.len() {
135						buf.push_str(", ");
136					}
137				}
138				buf.push_str("}");
139				write!(f, "{}", &buf)
140			}
141		}
142	}
143}