ironcalc_base/
calc_result.rs1use std::cmp::Ordering;
2
3use crate::expressions::{parser::ArrayNode, token::Error, types::CellReferenceIndex};
4
5#[derive(Clone)]
6pub struct Range {
7 pub left: CellReferenceIndex,
8 pub right: CellReferenceIndex,
9}
10
11#[derive(Clone)]
12pub(crate) enum CalcResult {
13 String(String),
14 Number(f64),
15 Boolean(bool),
16 Error {
17 error: Error,
18 origin: CellReferenceIndex,
19 message: String,
20 },
21 Range {
22 left: CellReferenceIndex,
23 right: CellReferenceIndex,
24 },
25 EmptyCell,
26 EmptyArg,
27 Array(Vec<Vec<ArrayNode>>),
28 Lambda(usize),
29}
30
31impl CalcResult {
32 pub fn new_error(error: Error, origin: CellReferenceIndex, message: String) -> CalcResult {
33 CalcResult::Error {
34 error,
35 origin,
36 message,
37 }
38 }
39 pub fn new_args_number_error(origin: CellReferenceIndex) -> CalcResult {
40 CalcResult::Error {
41 error: Error::ERROR,
42 origin,
43 message: "Wrong number of arguments".to_string(),
44 }
45 }
46 pub fn is_error(&self) -> bool {
47 matches!(self, CalcResult::Error { .. })
48 }
49}
50
51impl Ord for CalcResult {
52 fn cmp(&self, other: &Self) -> Ordering {
54 match (self, other) {
55 (CalcResult::Number(value1), CalcResult::Number(value2)) => {
56 if (value2 - value1).abs() < f64::EPSILON {
57 return Ordering::Equal;
58 }
59 if value1 < value2 {
60 return Ordering::Less;
61 }
62 Ordering::Greater
63 }
64 (CalcResult::Number(_value1), CalcResult::String(_value2)) => Ordering::Less,
65 (CalcResult::Number(_value1), CalcResult::Boolean(_value2)) => Ordering::Less,
66 (CalcResult::String(value1), CalcResult::String(value2)) => {
67 let value1 = value1.to_uppercase();
68 let value2 = value2.to_uppercase();
69 value1.cmp(&value2)
70 }
71 (CalcResult::String(_value1), CalcResult::Boolean(_value2)) => Ordering::Less,
72 (CalcResult::Boolean(value1), CalcResult::Boolean(value2)) => {
73 if value1 == value2 {
74 return Ordering::Equal;
75 }
76 if *value1 {
77 return Ordering::Greater;
78 }
79 Ordering::Less
80 }
81 (CalcResult::EmptyCell, CalcResult::String(_value2)) => Ordering::Greater,
82 (CalcResult::EmptyArg, CalcResult::String(_value2)) => Ordering::Greater,
83 (CalcResult::String(_value1), CalcResult::EmptyCell) => Ordering::Less,
84 (CalcResult::EmptyCell, CalcResult::Number(_value2)) => Ordering::Greater,
85 (CalcResult::EmptyArg, CalcResult::Number(_value2)) => Ordering::Greater,
86 (CalcResult::Number(_value1), CalcResult::EmptyCell) => Ordering::Less,
87 (CalcResult::EmptyCell, CalcResult::EmptyCell) => Ordering::Equal,
88 (CalcResult::EmptyCell, CalcResult::EmptyArg) => Ordering::Equal,
89 (CalcResult::EmptyArg, CalcResult::EmptyCell) => Ordering::Equal,
90 (CalcResult::EmptyArg, CalcResult::EmptyArg) => Ordering::Equal,
91 (_, _) => Ordering::Greater,
93 }
94 }
95}
96
97impl PartialOrd for CalcResult {
98 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
99 Some(self.cmp(other))
100 }
101}
102
103impl PartialEq for CalcResult {
104 fn eq(&self, other: &Self) -> bool {
105 self.cmp(other) == Ordering::Equal
106 }
107}
108
109impl Eq for CalcResult {}