@@ -194,39 +194,23 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
194
194
// basic operators
195
195
let value = match function {
196
196
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) ?;
228
209
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 ) ?)
230
214
}
231
215
_ => return Err ( Error :: TypeError ) ,
232
216
} ;
@@ -318,6 +302,54 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
318
302
Ok ( value)
319
303
}
320
304
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
+
321
353
#[ cfg( test) ]
322
354
mod test {
323
355
use super :: * ;
0 commit comments