1pub fn evaluate(expr: &str) -> Result<f32, &str> {
17 let mut stack:Vec<f32> = Vec::new();
18 for token in expr.split_whitespace() {
19 let wrapped_operand = token.parse::<f32>();
20 let is_operator = wrapped_operand.is_err();
21 if is_operator {
22 if stack.len() < 2 {
23 return Err("Unsufficient operands before operator");
24 }
25 let operand2 = stack.pop().expect("expected f32 values in stack");
29 let operand1 = stack.pop().expect("expected f32 values in stack");
30 let result = match token {
31 "+" => operand1 + operand2,
32 "-" => operand1 - operand2,
33 "*" => operand1 * operand2,
34 "/" => operand1 / operand2,
35 _ => return Err("Unsupported operator")
36 };
37 stack.push(result);
38 } else {
39 stack.push(wrapped_operand.unwrap());
40 }
41 }
42
43 if stack.len() != 1 {
44 return Err("Remaining untreated operands. Probably missing operator.");
45 }
46 return Ok(stack.pop().expect("expected a f32 value remaining in stack"));
47}
48
49#[test]
50fn it_adds() {
51 let result = evaluate("1 2 +");
52 assert_eq!(result.unwrap(), 3.0);
53}
54
55#[test]
56fn it_substracts() {
57 let result = evaluate("1 2 -");
58 assert_eq!(result.unwrap(), -1.0);
59}
60
61#[test]
62fn it_multiplies() {
63 let result = evaluate("6 7 *");
64 assert_eq!(result.unwrap(), 42.0);
65}
66
67#[test]
68fn it_divides() {
69 let result = evaluate("1 2 /");
70 assert_eq!(result.unwrap(), 0.5);
71}
72
73#[test]
74fn it_evaluates_complex_expressions() {
75 let result = evaluate("1 2 + 8 * 5 1 - / 1 - 2 /");
77 assert_eq!(result.unwrap(), 2.5);
78}
79
80#[test]
81fn it_allows_multiple_shitespaces() {
82 let result = evaluate("1 2 +\t3 -");
83 assert_eq!(result.unwrap(), 0.0);
84}
85
86#[test]
87fn it_panics_for_unsupported_characters() {
88 let result = evaluate("1 2 t");
89 assert_eq!(result.unwrap_err(), "Unsupported operator");
90}
91
92#[test]
93fn it_panics_for_unsufficient_operands() {
94 let result = evaluate("1 +");
95 assert_eq!(result.unwrap_err(), "Unsufficient operands before operator");
96}
97
98#[test]
99fn it_panics_for_unsufficient_operators() {
100 let result = evaluate("1 2 3 +");
101 assert_eq!(result.unwrap_err(),
102 "Remaining untreated operands. Probably missing operator.");
103}