Skip to content

Commit 1cb09cb

Browse files
committed
Added math functions
1 parent a3a2e70 commit 1cb09cb

File tree

1 file changed

+227
-6
lines changed

1 file changed

+227
-6
lines changed

primitives/src/targeting/eval.rs

Lines changed: 227 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::BigNum;
22
use serde::{Deserialize, Serialize};
33
use serde_json::{value::Value as SerdeValue, Number};
4-
use std::{convert::TryFrom, fmt, ops::Div, str::FromStr};
4+
use std::{convert::TryFrom, fmt, ops::{Div, Mul, Rem, Add, Sub}, str::FromStr};
55

66
pub type Map = serde_json::value::Map<String, SerdeValue>;
77

@@ -83,8 +83,13 @@ impl TryFrom<SerdeValue> for Value {
8383
#[serde(rename_all = "camelCase")]
8484
// TODO: https://github.com/AdExNetwork/adex-validator-stack-rust/issues/296
8585
pub enum Function {
86-
/// Math `div`
8786
Div(Box<Rule>, Box<Rule>),
87+
Mul(Box<Rule>, Box<Rule>),
88+
Mod(Box<Rule>, Box<Rule>),
89+
Add(Box<Rule>, Box<Rule>),
90+
Sub(Box<Rule>, Box<Rule>),
91+
Max(Box<Rule>, Box<Rule>),
92+
Min(Box<Rule>, Box<Rule>),
8893
If(Box<Rule>, Box<Rule>),
8994
And(Box<Rule>, Box<Rule>),
9095
Intersects(Box<Rule>, Box<Rule>),
@@ -217,6 +222,144 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
217222

218223
Some(value)
219224
}
225+
Function::Mul(first_rule, second_rule) => {
226+
let first_eval = first_rule.eval(input, output)?.ok_or(Error::TypeError)?;
227+
let second_eval = second_rule.eval(input, output)?.ok_or(Error::TypeError)?;
228+
229+
let value = match (first_eval, second_eval) {
230+
(Value::BigNum(bignum), rhs_value) => {
231+
let rhs_bignum = BigNum::try_from(rhs_value)?;
232+
233+
Value::BigNum(bignum.mul(rhs_bignum))
234+
},
235+
(lhs_value, Value::BigNum(rhs_bignum)) => {
236+
let lhs_bignum = BigNum::try_from(lhs_value)?;
237+
238+
Value::BigNum(lhs_bignum.mul(rhs_bignum))
239+
}
240+
(Value::Number(lhs), Value::Number(rhs)) => {
241+
Value::Number(math_operator(lhs, rhs, MathOperator::Multiplication)?)
242+
}
243+
_ => return Err(Error::TypeError),
244+
};
245+
246+
Some(value)
247+
}
248+
Function::Mod(first_rule, second_rule) => {
249+
let first_eval = first_rule.eval(input, output)?.ok_or(Error::TypeError)?;
250+
let second_eval = second_rule.eval(input, output)?.ok_or(Error::TypeError)?;
251+
252+
let value = match (first_eval, second_eval) {
253+
(Value::BigNum(bignum), rhs_value) => {
254+
let rhs_bignum = BigNum::try_from(rhs_value)?;
255+
256+
Value::BigNum(bignum.rem(rhs_bignum))
257+
},
258+
(lhs_value, Value::BigNum(rhs_bignum)) => {
259+
let lhs_bignum = BigNum::try_from(lhs_value)?;
260+
261+
Value::BigNum(lhs_bignum.rem(rhs_bignum))
262+
}
263+
(Value::Number(lhs), Value::Number(rhs)) => {
264+
Value::Number(math_operator(lhs, rhs, MathOperator::Modulus)?)
265+
}
266+
_ => return Err(Error::TypeError),
267+
};
268+
269+
Some(value)
270+
}
271+
Function::Add(first_rule, second_rule) => {
272+
let first_eval = first_rule.eval(input, output)?.ok_or(Error::TypeError)?;
273+
let second_eval = second_rule.eval(input, output)?.ok_or(Error::TypeError)?;
274+
275+
let value = match (first_eval, second_eval) {
276+
(Value::BigNum(bignum), rhs_value) => {
277+
let rhs_bignum = BigNum::try_from(rhs_value)?;
278+
279+
Value::BigNum(bignum.add(rhs_bignum))
280+
},
281+
(lhs_value, Value::BigNum(rhs_bignum)) => {
282+
let lhs_bignum = BigNum::try_from(lhs_value)?;
283+
284+
Value::BigNum(lhs_bignum.add(rhs_bignum))
285+
}
286+
(Value::Number(lhs), Value::Number(rhs)) => {
287+
Value::Number(math_operator(lhs, rhs, MathOperator::Addition)?)
288+
}
289+
_ => return Err(Error::TypeError),
290+
};
291+
292+
Some(value)
293+
}
294+
Function::Sub(first_rule, second_rule) => {
295+
let first_eval = first_rule.eval(input, output)?.ok_or(Error::TypeError)?;
296+
let second_eval = second_rule.eval(input, output)?.ok_or(Error::TypeError)?;
297+
298+
let value = match (first_eval, second_eval) {
299+
(Value::BigNum(bignum), rhs_value) => {
300+
let rhs_bignum = BigNum::try_from(rhs_value)?;
301+
302+
Value::BigNum(bignum.sub(rhs_bignum))
303+
},
304+
(lhs_value, Value::BigNum(rhs_bignum)) => {
305+
let lhs_bignum = BigNum::try_from(lhs_value)?;
306+
307+
Value::BigNum(lhs_bignum.sub(rhs_bignum))
308+
}
309+
(Value::Number(lhs), Value::Number(rhs)) => {
310+
Value::Number(math_operator(lhs, rhs, MathOperator::Subtraction)?)
311+
}
312+
_ => return Err(Error::TypeError),
313+
};
314+
315+
Some(value)
316+
}
317+
Function::Max(first_rule, second_rule) => {
318+
let first_eval = first_rule.eval(input, output)?.ok_or(Error::TypeError)?;
319+
let second_eval = second_rule.eval(input, output)?.ok_or(Error::TypeError)?;
320+
321+
let value = match (first_eval, second_eval) {
322+
(Value::BigNum(bignum), rhs_value) => {
323+
let rhs_bignum = BigNum::try_from(rhs_value)?;
324+
325+
Value::BigNum(bignum.max(rhs_bignum))
326+
},
327+
(lhs_value, Value::BigNum(rhs_bignum)) => {
328+
let lhs_bignum = BigNum::try_from(lhs_value)?;
329+
330+
Value::BigNum(lhs_bignum.max(rhs_bignum))
331+
}
332+
(Value::Number(lhs), Value::Number(rhs)) => {
333+
Value::Number(math_operator(lhs, rhs, MathOperator::Max)?)
334+
}
335+
_ => return Err(Error::TypeError),
336+
};
337+
338+
Some(value)
339+
}
340+
Function::Min(first_rule, second_rule) => {
341+
let first_eval = first_rule.eval(input, output)?.ok_or(Error::TypeError)?;
342+
let second_eval = second_rule.eval(input, output)?.ok_or(Error::TypeError)?;
343+
344+
let value = match (first_eval, second_eval) {
345+
(Value::BigNum(bignum), rhs_value) => {
346+
let rhs_bignum = BigNum::try_from(rhs_value)?;
347+
348+
Value::BigNum(bignum.min(rhs_bignum))
349+
},
350+
(lhs_value, Value::BigNum(rhs_bignum)) => {
351+
let lhs_bignum = BigNum::try_from(lhs_value)?;
352+
353+
Value::BigNum(lhs_bignum.min(rhs_bignum))
354+
}
355+
(Value::Number(lhs), Value::Number(rhs)) => {
356+
Value::Number(math_operator(lhs, rhs, MathOperator::Min)?)
357+
}
358+
_ => return Err(Error::TypeError),
359+
};
360+
361+
Some(value)
362+
}
220363
Function::If(first_rule, second_rule) => {
221364
let eval_if = eval(input, output, first_rule)?
222365
.ok_or(Error::TypeError)?
@@ -303,15 +446,45 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
303446
}
304447

305448
enum MathOperator {
306-
Division
449+
Division,
450+
Multiplication,
451+
Modulus,
452+
Addition,
453+
Subtraction,
454+
Max,
455+
Min,
307456
}
308457

309458
fn handle_u64(lhs: u64, rhs: u64, ops: MathOperator) -> Result<Number, Error> {
310459
match ops {
311460
MathOperator::Division => {
312461
let divided = lhs.checked_div(rhs).ok_or(Error::TypeError)?;
313462
Ok(divided.into())
314-
}
463+
},
464+
MathOperator::Multiplication => {
465+
let multiplied = lhs.checked_mul(rhs).ok_or(Error::TypeError)?;
466+
Ok(multiplied.into())
467+
},
468+
MathOperator::Modulus => {
469+
let modulus = lhs.checked_rem(rhs).ok_or(Error::TypeError)?;
470+
Ok(modulus.into())
471+
},
472+
MathOperator::Addition => {
473+
let added = lhs.checked_add(rhs).ok_or(Error::TypeError)?;
474+
Ok(added.into())
475+
},
476+
MathOperator::Subtraction => {
477+
let subtracted = lhs.checked_sub(rhs).ok_or(Error::TypeError)?;
478+
Ok(subtracted.into())
479+
},
480+
MathOperator::Max => {
481+
let max = lhs.max(rhs);
482+
Ok(max.into())
483+
},
484+
MathOperator::Min => {
485+
let min = lhs.min(rhs);
486+
Ok(min.into())
487+
},
315488
}
316489
}
317490

@@ -320,7 +493,31 @@ fn handle_i64(lhs: i64, rhs: i64, ops: MathOperator) -> Result<Number, Error> {
320493
MathOperator::Division => {
321494
let divided = lhs.checked_div(rhs).ok_or(Error::TypeError)?;
322495
Ok(divided.into())
323-
}
496+
},
497+
MathOperator::Multiplication => {
498+
let multiplied = lhs.checked_mul(rhs).ok_or(Error::TypeError)?;
499+
Ok(multiplied.into())
500+
},
501+
MathOperator::Modulus => {
502+
let modulus = lhs.checked_rem(rhs).ok_or(Error::TypeError)?;
503+
Ok(modulus.into())
504+
},
505+
MathOperator::Addition => {
506+
let added = lhs.checked_add(rhs).ok_or(Error::TypeError)?;
507+
Ok(added.into())
508+
},
509+
MathOperator::Subtraction => {
510+
let subtracted = lhs.checked_sub(rhs).ok_or(Error::TypeError)?;
511+
Ok(subtracted.into())
512+
},
513+
MathOperator::Max => {
514+
let max = lhs.max(rhs);
515+
Ok(max.into())
516+
},
517+
MathOperator::Min => {
518+
let min = lhs.min(rhs);
519+
Ok(min.into())
520+
},
324521
}
325522
}
326523

@@ -329,7 +526,31 @@ fn handle_f64(lhs: f64, rhs: f64, ops:MathOperator) -> Result<Number, Error> {
329526
MathOperator::Division => {
330527
let divided = lhs.div(rhs);
331528
Ok(Number::from_f64(divided).ok_or(Error::TypeError)?)
332-
}
529+
},
530+
MathOperator::Multiplication => {
531+
let multiplied = lhs.mul(rhs);
532+
Ok(Number::from_f64(multiplied).ok_or(Error::TypeError)?)
533+
},
534+
MathOperator::Modulus => {
535+
let modulus = lhs.rem(rhs);
536+
Ok(Number::from_f64(modulus).ok_or(Error::TypeError)?)
537+
},
538+
MathOperator::Addition => {
539+
let added = lhs.add(rhs);
540+
Ok(Number::from_f64(added).ok_or(Error::TypeError)?)
541+
},
542+
MathOperator::Subtraction => {
543+
let subtracted = lhs.sub(rhs);
544+
Ok(Number::from_f64(subtracted).ok_or(Error::TypeError)?)
545+
},
546+
MathOperator::Max => {
547+
let max = lhs.max(rhs);
548+
Ok(Number::from_f64(max).ok_or(Error::TypeError)?)
549+
},
550+
MathOperator::Min => {
551+
let min = lhs.min(rhs);
552+
Ok(Number::from_f64(min).ok_or(Error::TypeError)?)
553+
},
333554
}
334555
}
335556

0 commit comments

Comments
 (0)