1use std::fmt;
2
3#[derive(PartialEq, Debug, Clone)]
4pub enum Expr {
5 Literal(Literal),
6 Prefix(Prefix, Box<Expr>),
7 Infix(Infix, Box<Expr>, Box<Expr>),
8 Func {
9 name: String,
10 args: Vec<Expr>
11 },
12 Reference {
13 sheet: Option<String>,
14 reference: String
15 },
16 Array(Vec<Expr>),
17 Error(Error)
18}
19
20impl fmt::Display for Expr {
21 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22 match self {
23 Expr::Literal(l) => write!(f, "{}", l),
24 Expr::Prefix(p, e) => write!(f, "{}{}", p, e),
25 Expr::Infix(p, a, b) => write!(f, "({}{}{})", a, p, b),
26 Expr::Func{name, args} => {
27 let output = format!("{}({})", name, exprs_string(args));
28 write!(f, "{}", output)
29 },
30 Expr::Reference{sheet, reference} => {
31 match sheet {
32 Some(s) => {
33 write!(f, "{}!{}", s, reference)
34 },
35 None => write!(f, "{}", reference)
36 }
37 },
38 Expr::Array(arr) => write!(f, "{{{}}}", exprs_string(arr)),
39 Expr::Error(e) => write!(f, "{}", e)
40 }
41 }
42}
43
44fn exprs_string(v: &Vec<Expr>) -> String {
45 let mut output = String::new();
46 for (i, arg) in v.iter().enumerate() {
47 if i == v.len()-1 {
48 output.push_str(&arg.to_string());
49 } else {
50 output.push_str(&arg.to_string());
51 output.push_str(", ");
52 }
53 }
54 output
55}
56
57impl From<f64> for Expr {
58 fn from(f: f64) -> Expr {
59 Expr::Literal(Literal::from(f)) }
60}
61
62impl From<String> for Expr {
63 fn from(s: String) -> Expr {
64 Expr::Literal(Literal::from(s))
65 }
66}
67
68impl From<&str> for Expr {
69 fn from(s: &str) -> Expr {
70 Expr::from(s.to_string())
71 }
72}
73
74impl From<bool> for Expr {
75 fn from(b: bool) -> Expr {
76 Expr::Literal(Literal::from(b))
77 }
78}
79
80#[derive(Debug, PartialEq, Eq, Clone)]
81pub enum Error {
82 Null,
83 Div,
84 Value,
85 Ref,
86 Name,
87 Num,
88 NA,
89 GettingData
90}
91
92impl fmt::Display for Error {
93 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94 match self {
95 Error::Null => write!(f, "#NULL!"),
96 Error::Div => write!(f, "#DIV/0!"),
97 Error::Value => write!(f, "#VALUE!"),
98 Error::Ref => write!(f, "#REF!"),
99 Error::Name => write!(f, "#NAME!"),
100 Error::Num => write!(f, "#NUM!"),
101 Error::NA => write!(f, "#N/A!"),
102 Error::GettingData => write!(f, "#GETTING_DATA")
103 }
104 }
105}
106
107#[derive(PartialEq, Debug, Clone)]
108pub enum Literal {
109 Number(f64),
110 Boolean(bool),
111 Text(String),
112}
113
114impl From<f64> for Literal {
115 fn from(f: f64) -> Literal {
116 Literal::Number(f)
117 }
118}
119
120impl From<String> for Literal {
121 fn from(s: String) -> Literal {
122 Literal::Text(s)
123 }
124}
125
126impl From<&str> for Literal {
127 fn from(s: &str) -> Literal {
128 Literal::Text(s.to_string())
129 }
130}
131
132impl From<bool> for Literal {
133 fn from(b: bool) -> Literal {
134 Literal::Boolean(b)
135 }
136}
137
138impl fmt::Display for Literal {
139 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
140 match self {
141 Literal::Number(x) => write!(f, "{}", x),
142 Literal::Boolean(b) => {
143 if *b {
144 write!(f, "TRUE")
145 } else {
146 write!(f, "FALSE")
147 }
148 },
149 Literal::Text(s) => write!(f, "{}", s)
150 }
151 }
152}
153
154#[derive(PartialEq, Eq, Debug, Clone)]
155pub enum Prefix {
156 Plus,
157 Minus,
158}
159
160impl fmt::Display for Prefix {
161 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
162 match self {
163 Prefix::Plus => write!(f, "+"),
164 Prefix::Minus => write!(f, "-"),
165 }
166 }
167}
168
169
170#[derive(PartialEq, Eq, Debug, Clone)]
171pub enum Infix {
172 Plus,
173 Minus,
174 Divide,
175 Multiply,
176 Exponent,
177 Ampersand,
178 Equal,
179 NotEqual,
180 GreaterThanEqual,
181 LessThanEqual,
182 GreaterThan,
183 LessThan,
184}
185
186impl fmt::Display for Infix {
187 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
188 match self {
189 Infix::Plus => write!(f, "+"),
190 Infix::Minus => write!(f, "-"),
191 Infix::Divide => write!(f, "/"),
192 Infix::Multiply => write!(f, "*"),
193 Infix::Exponent => write!(f, "^"),
194 Infix::Ampersand => write!(f, "&"),
195 Infix::Equal => write!(f, "="),
196 Infix::NotEqual => write!(f, "<>"),
197 Infix::GreaterThanEqual => write!(f, ">="),
198 Infix::LessThanEqual => write!(f, "<="),
199 Infix::GreaterThan => write!(f, ">"),
200 Infix::LessThan => write!(f, "<")
201 }
202 }
203}
204
205#[derive(PartialEq, Eq, PartialOrd, Debug, Clone)]
206pub enum Precedence {
207 Lowest,
208 Comparison,
209 Concat,
210 PlusMinus,
211 MultDiv,
212 Exponent,
213 Percent,
214}