1use std::cmp;
4
5use std::convert::TryInto;
6
7use serde::{Deserialize, Serialize};
8
9use ordered_float::NotNan;
10
11use super::types::*;
12
13use self::Value::*;
14
15#[derive(Serialize, Deserialize, Eq, PartialEq, Hash, Clone, Debug)]
16#[serde(untagged)]
17#[repr(u8)]
18pub enum Value {
19 Int64(i64),
20 Float64(NotNan<f64>),
21 Bool(bool),
22 Vector(Vec<Value>),
23}
24
25impl From<bool> for Value {
26 fn from(value: bool) -> Self {
27 Value::Bool(value)
28 }
29}
30
31impl TryInto<bool> for Value {
32 type Error = String;
33
34 fn try_into(self) -> Result<bool, Self::Error> {
35 match self {
36 Value::Bool(value) => Ok(value),
37 _ => Err(format!("Unable to convert {:?} to boolean.", self)),
38 }
39 }
40}
41
42impl From<i64> for Value {
43 fn from(value: i64) -> Self {
44 Value::Int64(value)
45 }
46}
47
48impl TryInto<i64> for Value {
49 type Error = String;
50
51 fn try_into(self) -> Result<i64, Self::Error> {
52 match self {
53 Value::Int64(value) => Ok(value),
54 _ => Err(format!("Unable to convert {:?} to integer.", self)),
55 }
56 }
57}
58
59impl TryInto<f64> for Value {
60 type Error = String;
61
62 fn try_into(self) -> Result<f64, Self::Error> {
63 match self {
64 Value::Float64(value) => Ok(value.into_inner()),
65 _ => Err(format!("Unable to convert {:?} to float.", self)),
66 }
67 }
68}
69
70impl Value {
71 pub fn get_type(&self) -> Type {
72 match self {
73 Value::Int64(_) => Type::Int64,
74 Value::Float64(_) => Type::Float64,
75 Value::Bool(_) => Type::Bool,
76 Value::Vector(elements) => Type::Vector {
77 element_type: Box::new(
78 elements
81 .first()
82 .map(|element| element.get_type())
83 .unwrap_or(Type::Unknown),
84 ),
85 },
86 }
87 }
88
89 pub fn is_int(&self) -> bool {
90 matches!(self, Value::Int64(_))
91 }
92
93 pub fn is_float(&self) -> bool {
94 matches!(self, Value::Float64(_))
95 }
96
97 pub fn is_numeric(&self) -> bool {
98 matches!(self, Value::Int64(_) | Value::Float64(_))
99 }
100
101 pub fn is_bool(&self) -> bool {
102 matches!(self, Value::Bool(_))
103 }
104
105 pub fn is_vector(&self) -> bool {
106 matches!(self, Value::Vector(_))
107 }
108
109 pub fn unwrap_bool(&self) -> bool {
110 match self {
111 Value::Bool(value) => *value,
112 _ => panic!("Value {:?} is not a Bool.", self),
113 }
114 }
115
116 pub fn unwrap_int64(&self) -> i64 {
117 match self {
118 Value::Int64(value) => *value,
119 _ => panic!("Value {:?} is not an Int64.", self),
120 }
121 }
122
123 pub fn unwrap_float64(&self) -> NotNan<f64> {
124 match self {
125 Value::Float64(value) => *value,
126 _ => panic!("Value {:?} is not a Float64.", self),
127 }
128 }
129
130 pub fn unwrap_vector(&self) -> &Vec<Value> {
131 match self {
132 Value::Vector(vector) => vector,
133 _ => panic!("Value {:?} is not a Vector.", self),
134 }
135 }
136
137 #[inline(always)]
138 pub fn apply_not(self) -> Value {
139 match self {
140 Bool(operand) => Bool(!operand),
141 operand => panic!("Invalid operand in expression (! {:?}).", operand),
142 }
143 }
144
145 #[inline(always)]
146 pub fn apply_floor(self) -> Value {
147 match self {
148 Float64(operand) => Int64(operand.floor() as i64),
149 Int64(operand) => Int64(operand),
150 operand => panic!("Invalid operand in expression (floor {:?}).", operand),
151 }
152 }
153
154 #[inline(always)]
155 pub fn apply_ceil(self) -> Value {
156 match self {
157 Float64(operand) => Int64(operand.ceil() as i64),
158 operand => panic!("Invalid operand in expression (ceil {:?}).", operand),
159 }
160 }
161
162 #[inline(always)]
163 pub fn apply_abs(self) -> Value {
164 match self {
165 Float64(operand) => Float64(NotNan::new(operand.abs()).unwrap()),
166 Int64(operand) => Int64(operand.abs()),
167 operand => panic!("Invalid operand in expression (abs {:?}).", operand),
168 }
169 }
170
171 #[inline(always)]
172 pub fn apply_sgn(self) -> Value {
173 match self {
174 Float64(operand) => Float64(NotNan::new(operand.signum()).unwrap()),
175 Int64(operand) => Int64(operand.signum()),
176 operand => panic!("Invalid operand in expression (sgn {:?}).", operand),
177 }
178 }
179
180 #[inline(always)]
181 pub fn apply_trc(self) -> Value {
182 match self {
183 Float64(operand) => Int64(operand.trunc() as i64),
184 operand => panic!("Invalid operand in expression (trc {:?}).", operand),
185 }
186 }
187
188 #[inline(always)]
189 pub fn apply_minus(self) -> Value {
190 match self {
191 Int64(operand) => Int64(-operand),
192 Float64(operand) => Float64(-operand),
193 operand => panic!("Invalid operand in expression (- {:?}).", operand),
194 }
195 }
196
197 #[inline(always)]
198 pub fn apply_add(self, other: Value) -> Value {
199 match (self, other) {
200 (Int64(left), Int64(right)) => Int64(left + right),
201 (Float64(left), Float64(right)) => Float64(left + right),
202 (Int64(left), Float64(right)) => Float64(NotNan::new(left as f64).unwrap() + right),
203 (Float64(left), Int64(right)) => Float64(left + NotNan::new(right as f64).unwrap()),
204 (left, right) => panic!("Invalid operands in expression ({:?} + {:?}).", left, right),
205 }
206 }
207
208 #[inline(always)]
209 pub fn apply_sub(self, other: Value) -> Value {
210 match (self, other) {
211 (Int64(left), Int64(right)) => Int64(left - right),
212 (Float64(left), Float64(right)) => Float64(left - right),
213 (Int64(left), Float64(right)) => Float64(NotNan::new(left as f64).unwrap() - right),
214 (Float64(left), Int64(right)) => Float64(left - NotNan::new(right as f64).unwrap()),
215 (left, right) => panic!("Invalid operands in expression ({:?} - {:?}).", left, right),
216 }
217 }
218
219 #[inline(always)]
220 pub fn apply_mul(self, other: Value) -> Value {
221 match (self, other) {
222 (Int64(left), Int64(right)) => Int64(left * right),
223 (Float64(left), Float64(right)) => Float64(left * right),
224 (Int64(left), Float64(right)) => Float64(NotNan::new(left as f64).unwrap() * right),
225 (Float64(left), Int64(right)) => Float64(left * NotNan::new(right as f64).unwrap()),
226 (left, right) => panic!("Invalid operands in expression ({:?} * {:?}).", left, right),
227 }
228 }
229
230 #[inline(always)]
231 pub fn apply_floor_div(self, other: Value) -> Value {
232 match (self, other) {
233 (Int64(left), Int64(right)) => Int64(left.div_euclid(right)),
234 (Float64(left), Float64(right)) => Int64((left / right).floor() as i64),
235 (Int64(left), Float64(right)) => {
236 Int64((NotNan::new(left as f64).unwrap() / right).floor() as i64)
237 }
238 (Float64(left), Int64(right)) => {
239 Int64((left / (NotNan::new(right as f64).unwrap()).floor()).into_inner() as i64)
240 }
241 (left, right) => panic!(
242 "Invalid operands in expression ({:?} // {:?}).",
243 left, right
244 ),
245 }
246 }
247
248 #[inline(always)]
249 pub fn apply_real_div(self, other: Value) -> Value {
250 match (self, other) {
251 (Int64(left), Int64(right)) => {
252 Float64(NotNan::new((left as f64) / (right as f64)).unwrap())
253 }
254 (Float64(left), Float64(right)) => Float64(left / right),
255 (left, right) => panic!("Invalid operands in expression ({:?} / {:?}).", left, right),
256 }
257 }
258
259 #[inline(always)]
260 pub fn apply_mod(self, other: Value) -> Value {
261 match (self, other) {
262 (Int64(left), Int64(right)) => Int64(left.rem_euclid(right)),
263 (Float64(left), Float64(right)) => Float64(left % right),
264 (left, right) => panic!("Invalid operands in expression ({:?} % {:?}).", left, right),
265 }
266 }
267
268 #[inline(always)]
269 pub fn apply_pow(self, other: Value) -> Value {
270 match (self, other) {
271 (Int64(left), Int64(right)) => {
272 Float64(NotNan::new((left as f64).powf(right as f64)).unwrap())
273 }
274 (Float64(left), Float64(right)) => {
275 Float64(NotNan::new(left.powf(right.into())).unwrap())
276 }
277 (left, right) => panic!(
278 "Invalid operands in expression ({:?} ** {:?}).",
279 left, right
280 ),
281 }
282 }
283
284 #[inline(always)]
285 pub fn apply_log(self, other: Value) -> Value {
286 match (self, other) {
287 (Int64(left), Int64(right)) => {
288 Float64(NotNan::new((left as f64).log(right as f64)).unwrap())
289 }
290 (Float64(left), Float64(right)) => {
291 Float64(NotNan::new(left.log(right.into())).unwrap())
292 }
293 (left, right) => panic!(
294 "Invalid operands in expression ({:?} log {:?}).",
295 left, right
296 ),
297 }
298 }
299
300 #[inline(always)]
301 pub fn apply_min(self, other: Value) -> Value {
302 match (self, other) {
303 (Int64(left), Int64(right)) => Int64(cmp::min(left, right)),
304 (Float64(left), Float64(right)) => Float64(cmp::min(left, right)),
305 (left, right) => panic!(
306 "Invalid operands in expression ({:?} min {:?}).",
307 left, right
308 ),
309 }
310 }
311
312 #[inline(always)]
313 pub fn apply_max(self, other: Value) -> Value {
314 match (self, other) {
315 (Int64(left), Int64(right)) => Int64(cmp::max(left, right)),
316 (Float64(left), Float64(right)) => Float64(cmp::max(left, right)),
317 (left, right) => panic!(
318 "Invalid operands in expression ({:?} max {:?}).",
319 left, right
320 ),
321 }
322 }
323
324 #[inline(always)]
325 pub fn apply_cmp_eq(self, other: Value) -> Value {
326 Value::Bool(self == other)
327 }
328
329 #[inline(always)]
330 pub fn apply_cmp_ne(self, other: Value) -> Value {
331 Value::Bool(self != other)
332 }
333
334 #[inline(always)]
335 pub fn apply_cmp_lt(self, other: Value) -> Value {
336 match (self, other) {
337 (Int64(left), Int64(right)) => Bool(left < right),
338 (Float64(left), Float64(right)) => Bool(left < right),
339 (Int64(left), Float64(right)) => Bool((left as f64) < right.into_inner()),
340 (Float64(left), Int64(right)) => Bool(left.into_inner() < (right as f64)),
341 (left, right) => panic!("Invalid operands in expression ({:?} < {:?}).", left, right),
342 }
343 }
344
345 #[inline(always)]
346 pub fn apply_cmp_le(self, other: Value) -> Value {
347 match (self, other) {
348 (Int64(left), Int64(right)) => Bool(left <= right),
349 (Float64(left), Float64(right)) => Bool(left <= right),
350 (Int64(left), Float64(right)) => Bool((left as f64) <= right.into_inner()),
351 (Float64(left), Int64(right)) => Bool(left.into_inner() <= (right as f64)),
352 (left, right) => panic!(
353 "Invalid operands in expression ({:?} <= {:?}).",
354 left, right
355 ),
356 }
357 }
358
359 #[inline(always)]
360 pub fn apply_cmp_ge(self, other: Value) -> Value {
361 match (self, other) {
362 (Int64(left), Int64(right)) => Bool(left >= right),
363 (Float64(left), Float64(right)) => Bool(left >= right),
364 (Int64(left), Float64(right)) => Bool((left as f64) >= right.into_inner()),
365 (Float64(left), Int64(right)) => Bool(left.into_inner() >= (right as f64)),
366 (left, right) => panic!(
367 "Invalid operands in expression ({:?} >= {:?}).",
368 left, right
369 ),
370 }
371 }
372
373 #[inline(always)]
374 pub fn apply_cmp_gt(self, other: Value) -> Value {
375 match (self, other) {
376 (Int64(left), Int64(right)) => Bool(left > right),
377 (Float64(left), Float64(right)) => Bool(left > right),
378 (Int64(left), Float64(right)) => Bool((left as f64) > right.into_inner()),
379 (Float64(left), Int64(right)) => Bool(left.into_inner() > (right as f64)),
380 (left, right) => panic!("Invalid operands in expression ({:?} > {:?}).", left, right),
381 }
382 }
383
384 #[inline(always)]
385 pub fn apply_sin(self) -> Value {
386 match self {
387 Float64(operand) => Float64(operand.sin().try_into().unwrap()),
388 operand => panic!("Invalid operand in expression (sin {:?}).", operand),
389 }
390 }
391
392 #[inline(always)]
393 pub fn apply_cos(self) -> Value {
394 match self {
395 Float64(operand) => Float64(operand.cos().try_into().unwrap()),
396 operand => panic!("Invalid operand in expression (sin {:?}).", operand),
397 }
398 }
399
400 #[inline(always)]
401 pub fn apply_tan(self) -> Value {
402 match self {
403 Float64(operand) => Float64(operand.tan().try_into().unwrap()),
404 operand => panic!("Invalid operand in expression (sin {:?}).", operand),
405 }
406 }
407}