Skip to content

Commit 46ad390

Browse files
authored
Merge pull request #299 from AdExNetwork/better-math-handling
Try to handle Division better
2 parents 2f2bcae + a3a2e70 commit 46ad390

File tree

1 file changed

+64
-32
lines changed

1 file changed

+64
-32
lines changed

primitives/src/targeting/eval.rs

Lines changed: 64 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -194,39 +194,23 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
194194
// basic operators
195195
let value = match function {
196196
Function::Div(first_rule, second_rule) => {
197-
let value = match first_rule.eval(input, output)?.ok_or(Error::TypeError)? {
198-
Value::Number(first_number) => {
199-
match second_rule.eval(input, output)?.ok_or(Error::TypeError)? {
200-
Value::Number(second_number) => {
201-
if let Some(num) = first_number.as_f64() {
202-
let divided =
203-
num.div(second_number.as_f64().ok_or(Error::TypeError)?);
204-
205-
Value::Number(Number::from_f64(divided).ok_or(Error::TypeError)?)
206-
} else if let Some(num) = first_number.as_i64() {
207-
let rhs = second_number.as_i64().ok_or(Error::TypeError)?;
208-
let divided = num.checked_div(rhs).ok_or(Error::TypeError)?;
209-
210-
Value::Number(divided.into())
211-
} else if let Some(num) = first_number.as_u64() {
212-
let rhs = second_number.as_u64().ok_or(Error::TypeError)?;
213-
let divided = num.checked_div(rhs).ok_or(Error::TypeError)?;
214-
215-
Value::Number(divided.into())
216-
} else {
217-
return Err(Error::TypeError);
218-
}
219-
}
220-
_ => return Err(Error::TypeError),
221-
}
222-
}
223-
Value::BigNum(first_bignum) => {
224-
let second_bignum = second_rule
225-
.eval(input, output)?
226-
.ok_or(Error::TypeError)?
227-
.try_bignum()?;
197+
let first_eval = first_rule.eval(input, output)?.ok_or(Error::TypeError)?;
198+
let second_eval = second_rule.eval(input, output)?.ok_or(Error::TypeError)?;
199+
200+
201+
let value = match (first_eval, second_eval) {
202+
(Value::BigNum(bignum), second_value) => {
203+
let second_bignum = BigNum::try_from(second_value)?;
204+
205+
Value::BigNum(bignum.div(second_bignum))
206+
},
207+
(lhs_value, Value::BigNum(rhs_bignum)) => {
208+
let lhs_bignum = BigNum::try_from(lhs_value)?;
228209

229-
Value::BigNum(first_bignum.div(second_bignum))
210+
Value::BigNum(lhs_bignum.div(rhs_bignum))
211+
}
212+
(Value::Number(lhs), Value::Number(rhs)) => {
213+
Value::Number(math_operator(lhs, rhs, MathOperator::Division)?)
230214
}
231215
_ => return Err(Error::TypeError),
232216
};
@@ -318,6 +302,54 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
318302
Ok(value)
319303
}
320304

305+
enum MathOperator {
306+
Division
307+
}
308+
309+
fn handle_u64(lhs: u64, rhs: u64, ops: MathOperator) -> Result<Number, Error> {
310+
match ops {
311+
MathOperator::Division => {
312+
let divided = lhs.checked_div(rhs).ok_or(Error::TypeError)?;
313+
Ok(divided.into())
314+
}
315+
}
316+
}
317+
318+
fn handle_i64(lhs: i64, rhs: i64, ops: MathOperator) -> Result<Number, Error> {
319+
match ops {
320+
MathOperator::Division => {
321+
let divided = lhs.checked_div(rhs).ok_or(Error::TypeError)?;
322+
Ok(divided.into())
323+
}
324+
}
325+
}
326+
327+
fn handle_f64(lhs: f64, rhs: f64, ops:MathOperator) -> Result<Number, Error> {
328+
match ops {
329+
MathOperator::Division => {
330+
let divided = lhs.div(rhs);
331+
Ok(Number::from_f64(divided).ok_or(Error::TypeError)?)
332+
}
333+
}
334+
}
335+
336+
fn math_operator(lhs: Number, rhs: Number, ops: MathOperator) -> Result<Number, Error> {
337+
match (lhs.as_u64(), rhs.as_u64()) {
338+
(Some(lhs), Some(rhs)) => handle_u64(lhs, rhs, ops),
339+
_ => {
340+
match (lhs.as_i64(), rhs.as_i64()) {
341+
(Some(lhs), Some(rhs)) => handle_i64(lhs, rhs, ops),
342+
_ => {
343+
match (lhs.as_f64(), rhs.as_f64()) {
344+
(Some(lhs), Some(rhs)) => handle_f64(lhs, rhs, ops),
345+
_ => Err(Error::TypeError)
346+
}
347+
}
348+
}
349+
}
350+
}
351+
}
352+
321353
#[cfg(test)]
322354
mod test {
323355
use super::*;

0 commit comments

Comments
 (0)