1
1
use crate :: BigNum ;
2
2
use serde:: { Deserialize , Serialize } ;
3
3
use serde_json:: { value:: Value as SerdeValue , Number } ;
4
- use std:: { convert:: TryFrom , fmt, ops:: Div , str:: FromStr } ;
4
+ use std:: {
5
+ convert:: TryFrom ,
6
+ fmt,
7
+ ops:: { Add , Div , Mul , Rem , Sub } ,
8
+ str:: FromStr ,
9
+ } ;
5
10
6
11
pub type Map = serde_json:: value:: Map < String , SerdeValue > ;
7
12
@@ -83,8 +88,14 @@ impl TryFrom<SerdeValue> for Value {
83
88
#[ serde( rename_all = "camelCase" ) ]
84
89
// TODO: https://github.com/AdExNetwork/adex-validator-stack-rust/issues/296
85
90
pub enum Function {
86
- /// Math `div`
91
+ MulDiv ( Box < Rule > , Box < Rule > , Box < Rule > ) ,
87
92
Div ( Box < Rule > , Box < Rule > ) ,
93
+ Mul ( Box < Rule > , Box < Rule > ) ,
94
+ Mod ( Box < Rule > , Box < Rule > ) ,
95
+ Add ( Box < Rule > , Box < Rule > ) ,
96
+ Sub ( Box < Rule > , Box < Rule > ) ,
97
+ Max ( Box < Rule > , Box < Rule > ) ,
98
+ Min ( Box < Rule > , Box < Rule > ) ,
88
99
If ( Box < Rule > , Box < Rule > ) ,
89
100
And ( Box < Rule > , Box < Rule > ) ,
90
101
Intersects ( Box < Rule > , Box < Rule > ) ,
@@ -193,17 +204,31 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
193
204
194
205
// basic operators
195
206
let value = match function {
207
+ Function :: MulDiv ( first_rule, second_rule, third_rule) => {
208
+ let product = eval (
209
+ input,
210
+ output,
211
+ & Rule :: Function ( Function :: Mul ( first_rule. clone ( ) , second_rule. clone ( ) ) ) ,
212
+ ) ?
213
+ . ok_or ( Error :: TypeError ) ?;
214
+ let product_rule = Rule :: Value ( product) ;
215
+ let boxed_rule = Box :: new ( product_rule) ;
216
+ eval (
217
+ input,
218
+ output,
219
+ & Rule :: Function ( Function :: Div ( boxed_rule, third_rule. clone ( ) ) ) ,
220
+ ) ?
221
+ }
196
222
Function :: Div ( first_rule, second_rule) => {
197
223
let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
198
224
let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
199
225
200
-
201
226
let value = match ( first_eval, second_eval) {
202
227
( Value :: BigNum ( bignum) , second_value) => {
203
228
let second_bignum = BigNum :: try_from ( second_value) ?;
204
229
205
230
Value :: BigNum ( bignum. div ( second_bignum) )
206
- } ,
231
+ }
207
232
( lhs_value, Value :: BigNum ( rhs_bignum) ) => {
208
233
let lhs_bignum = BigNum :: try_from ( lhs_value) ?;
209
234
@@ -217,6 +242,144 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
217
242
218
243
Some ( value)
219
244
}
245
+ Function :: Mul ( first_rule, second_rule) => {
246
+ let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
247
+ let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
248
+
249
+ let value = match ( first_eval, second_eval) {
250
+ ( Value :: BigNum ( bignum) , rhs_value) => {
251
+ let rhs_bignum = BigNum :: try_from ( rhs_value) ?;
252
+
253
+ Value :: BigNum ( bignum. mul ( rhs_bignum) )
254
+ }
255
+ ( lhs_value, Value :: BigNum ( rhs_bignum) ) => {
256
+ let lhs_bignum = BigNum :: try_from ( lhs_value) ?;
257
+
258
+ Value :: BigNum ( lhs_bignum. mul ( rhs_bignum) )
259
+ }
260
+ ( Value :: Number ( lhs) , Value :: Number ( rhs) ) => {
261
+ Value :: Number ( math_operator ( lhs, rhs, MathOperator :: Multiplication ) ?)
262
+ }
263
+ _ => return Err ( Error :: TypeError ) ,
264
+ } ;
265
+
266
+ Some ( value)
267
+ }
268
+ Function :: Mod ( first_rule, second_rule) => {
269
+ let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
270
+ let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
271
+
272
+ let value = match ( first_eval, second_eval) {
273
+ ( Value :: BigNum ( bignum) , rhs_value) => {
274
+ let rhs_bignum = BigNum :: try_from ( rhs_value) ?;
275
+
276
+ Value :: BigNum ( bignum. rem ( rhs_bignum) )
277
+ }
278
+ ( lhs_value, Value :: BigNum ( rhs_bignum) ) => {
279
+ let lhs_bignum = BigNum :: try_from ( lhs_value) ?;
280
+
281
+ Value :: BigNum ( lhs_bignum. rem ( rhs_bignum) )
282
+ }
283
+ ( Value :: Number ( lhs) , Value :: Number ( rhs) ) => {
284
+ Value :: Number ( math_operator ( lhs, rhs, MathOperator :: Modulus ) ?)
285
+ }
286
+ _ => return Err ( Error :: TypeError ) ,
287
+ } ;
288
+
289
+ Some ( value)
290
+ }
291
+ Function :: Add ( first_rule, second_rule) => {
292
+ let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
293
+ let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
294
+
295
+ let value = match ( first_eval, second_eval) {
296
+ ( Value :: BigNum ( bignum) , rhs_value) => {
297
+ let rhs_bignum = BigNum :: try_from ( rhs_value) ?;
298
+
299
+ Value :: BigNum ( bignum. add ( rhs_bignum) )
300
+ }
301
+ ( lhs_value, Value :: BigNum ( rhs_bignum) ) => {
302
+ let lhs_bignum = BigNum :: try_from ( lhs_value) ?;
303
+
304
+ Value :: BigNum ( lhs_bignum. add ( rhs_bignum) )
305
+ }
306
+ ( Value :: Number ( lhs) , Value :: Number ( rhs) ) => {
307
+ Value :: Number ( math_operator ( lhs, rhs, MathOperator :: Addition ) ?)
308
+ }
309
+ _ => return Err ( Error :: TypeError ) ,
310
+ } ;
311
+
312
+ Some ( value)
313
+ }
314
+ Function :: Sub ( first_rule, second_rule) => {
315
+ let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
316
+ let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
317
+
318
+ let value = match ( first_eval, second_eval) {
319
+ ( Value :: BigNum ( bignum) , rhs_value) => {
320
+ let rhs_bignum = BigNum :: try_from ( rhs_value) ?;
321
+
322
+ Value :: BigNum ( bignum. sub ( rhs_bignum) )
323
+ }
324
+ ( lhs_value, Value :: BigNum ( rhs_bignum) ) => {
325
+ let lhs_bignum = BigNum :: try_from ( lhs_value) ?;
326
+
327
+ Value :: BigNum ( lhs_bignum. sub ( rhs_bignum) )
328
+ }
329
+ ( Value :: Number ( lhs) , Value :: Number ( rhs) ) => {
330
+ Value :: Number ( math_operator ( lhs, rhs, MathOperator :: Subtraction ) ?)
331
+ }
332
+ _ => return Err ( Error :: TypeError ) ,
333
+ } ;
334
+
335
+ Some ( value)
336
+ }
337
+ Function :: Max ( first_rule, second_rule) => {
338
+ let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
339
+ let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
340
+
341
+ let value = match ( first_eval, second_eval) {
342
+ ( Value :: BigNum ( bignum) , rhs_value) => {
343
+ let rhs_bignum = BigNum :: try_from ( rhs_value) ?;
344
+
345
+ Value :: BigNum ( bignum. max ( rhs_bignum) )
346
+ }
347
+ ( lhs_value, Value :: BigNum ( rhs_bignum) ) => {
348
+ let lhs_bignum = BigNum :: try_from ( lhs_value) ?;
349
+
350
+ Value :: BigNum ( lhs_bignum. max ( rhs_bignum) )
351
+ }
352
+ ( Value :: Number ( lhs) , Value :: Number ( rhs) ) => {
353
+ Value :: Number ( math_operator ( lhs, rhs, MathOperator :: Max ) ?)
354
+ }
355
+ _ => return Err ( Error :: TypeError ) ,
356
+ } ;
357
+
358
+ Some ( value)
359
+ }
360
+ Function :: Min ( first_rule, second_rule) => {
361
+ let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
362
+ let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
363
+
364
+ let value = match ( first_eval, second_eval) {
365
+ ( Value :: BigNum ( bignum) , rhs_value) => {
366
+ let rhs_bignum = BigNum :: try_from ( rhs_value) ?;
367
+
368
+ Value :: BigNum ( bignum. min ( rhs_bignum) )
369
+ }
370
+ ( lhs_value, Value :: BigNum ( rhs_bignum) ) => {
371
+ let lhs_bignum = BigNum :: try_from ( lhs_value) ?;
372
+
373
+ Value :: BigNum ( lhs_bignum. min ( rhs_bignum) )
374
+ }
375
+ ( Value :: Number ( lhs) , Value :: Number ( rhs) ) => {
376
+ Value :: Number ( math_operator ( lhs, rhs, MathOperator :: Min ) ?)
377
+ }
378
+ _ => return Err ( Error :: TypeError ) ,
379
+ } ;
380
+
381
+ Some ( value)
382
+ }
220
383
Function :: If ( first_rule, second_rule) => {
221
384
let eval_if = eval ( input, output, first_rule) ?
222
385
. ok_or ( Error :: TypeError ) ?
@@ -303,16 +466,46 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
303
466
}
304
467
305
468
enum MathOperator {
306
- Division
469
+ Division ,
470
+ Multiplication ,
471
+ Modulus ,
472
+ Addition ,
473
+ Subtraction ,
474
+ Max ,
475
+ Min ,
307
476
}
308
477
309
478
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
- }
479
+ match ops {
480
+ MathOperator :: Division => {
481
+ let divided = lhs. checked_div ( rhs) . ok_or ( Error :: TypeError ) ?;
482
+ Ok ( divided. into ( ) )
483
+ }
484
+ MathOperator :: Multiplication => {
485
+ let multiplied = lhs. checked_mul ( rhs) . ok_or ( Error :: TypeError ) ?;
486
+ Ok ( multiplied. into ( ) )
315
487
}
488
+ MathOperator :: Modulus => {
489
+ let modulus = lhs. checked_rem ( rhs) . ok_or ( Error :: TypeError ) ?;
490
+ Ok ( modulus. into ( ) )
491
+ }
492
+ MathOperator :: Addition => {
493
+ let added = lhs. checked_add ( rhs) . ok_or ( Error :: TypeError ) ?;
494
+ Ok ( added. into ( ) )
495
+ }
496
+ MathOperator :: Subtraction => {
497
+ let subtracted = lhs. checked_sub ( rhs) . ok_or ( Error :: TypeError ) ?;
498
+ Ok ( subtracted. into ( ) )
499
+ }
500
+ MathOperator :: Max => {
501
+ let max = lhs. max ( rhs) ;
502
+ Ok ( max. into ( ) )
503
+ }
504
+ MathOperator :: Min => {
505
+ let min = lhs. min ( rhs) ;
506
+ Ok ( min. into ( ) )
507
+ }
508
+ }
316
509
}
317
510
318
511
fn handle_i64 ( lhs : i64 , rhs : i64 , ops : MathOperator ) -> Result < Number , Error > {
@@ -321,32 +514,76 @@ fn handle_i64(lhs: i64, rhs: i64, ops: MathOperator) -> Result<Number, Error> {
321
514
let divided = lhs. checked_div ( rhs) . ok_or ( Error :: TypeError ) ?;
322
515
Ok ( divided. into ( ) )
323
516
}
517
+ MathOperator :: Multiplication => {
518
+ let multiplied = lhs. checked_mul ( rhs) . ok_or ( Error :: TypeError ) ?;
519
+ Ok ( multiplied. into ( ) )
520
+ }
521
+ MathOperator :: Modulus => {
522
+ let modulus = lhs. checked_rem ( rhs) . ok_or ( Error :: TypeError ) ?;
523
+ Ok ( modulus. into ( ) )
524
+ }
525
+ MathOperator :: Addition => {
526
+ let added = lhs. checked_add ( rhs) . ok_or ( Error :: TypeError ) ?;
527
+ Ok ( added. into ( ) )
528
+ }
529
+ MathOperator :: Subtraction => {
530
+ let subtracted = lhs. checked_sub ( rhs) . ok_or ( Error :: TypeError ) ?;
531
+ Ok ( subtracted. into ( ) )
532
+ }
533
+ MathOperator :: Max => {
534
+ let max = lhs. max ( rhs) ;
535
+ Ok ( max. into ( ) )
536
+ }
537
+ MathOperator :: Min => {
538
+ let min = lhs. min ( rhs) ;
539
+ Ok ( min. into ( ) )
540
+ }
324
541
}
325
542
}
326
543
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
- }
544
+ fn handle_f64 ( lhs : f64 , rhs : f64 , ops : MathOperator ) -> Result < Number , Error > {
545
+ match ops {
546
+ MathOperator :: Division => {
547
+ let divided = lhs. div ( rhs) ;
548
+ Ok ( Number :: from_f64 ( divided) . ok_or ( Error :: TypeError ) ?)
549
+ }
550
+ MathOperator :: Multiplication => {
551
+ let multiplied = lhs. mul ( rhs) ;
552
+ Ok ( Number :: from_f64 ( multiplied) . ok_or ( Error :: TypeError ) ?)
553
+ }
554
+ MathOperator :: Modulus => {
555
+ let modulus = lhs. rem ( rhs) ;
556
+ Ok ( Number :: from_f64 ( modulus) . ok_or ( Error :: TypeError ) ?)
333
557
}
558
+ MathOperator :: Addition => {
559
+ let added = lhs. add ( rhs) ;
560
+ Ok ( Number :: from_f64 ( added) . ok_or ( Error :: TypeError ) ?)
561
+ }
562
+ MathOperator :: Subtraction => {
563
+ let subtracted = lhs. sub ( rhs) ;
564
+ Ok ( Number :: from_f64 ( subtracted) . ok_or ( Error :: TypeError ) ?)
565
+ }
566
+ MathOperator :: Max => {
567
+ let max = lhs. max ( rhs) ;
568
+ Ok ( Number :: from_f64 ( max) . ok_or ( Error :: TypeError ) ?)
569
+ }
570
+ MathOperator :: Min => {
571
+ let min = lhs. min ( rhs) ;
572
+ Ok ( Number :: from_f64 ( min) . ok_or ( Error :: TypeError ) ?)
573
+ }
574
+ }
334
575
}
335
576
336
577
fn math_operator ( lhs : Number , rhs : Number , ops : MathOperator ) -> Result < Number , Error > {
337
578
match ( lhs. as_u64 ( ) , rhs. as_u64 ( ) ) {
338
579
( 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
- }
580
+ _ => match ( lhs. as_i64 ( ) , rhs. as_i64 ( ) ) {
581
+ ( Some ( lhs) , Some ( rhs) ) => handle_i64 ( lhs, rhs, ops) ,
582
+ _ => match ( lhs. as_f64 ( ) , rhs. as_f64 ( ) ) {
583
+ ( Some ( lhs) , Some ( rhs) ) => handle_f64 ( lhs, rhs, ops) ,
584
+ _ => Err ( Error :: TypeError ) ,
585
+ } ,
586
+ } ,
350
587
}
351
588
}
352
589
0 commit comments