@@ -97,7 +97,27 @@ pub enum Function {
97
97
Max ( Box < Rule > , Box < Rule > ) ,
98
98
Min ( Box < Rule > , Box < Rule > ) ,
99
99
If ( Box < Rule > , Box < Rule > ) ,
100
+ IfNot ( Box < Rule > , Box < Rule > ) ,
101
+ IfElse ( Box < Rule > , Box < Rule > , Box < Rule > ) ,
100
102
And ( Box < Rule > , Box < Rule > ) ,
103
+ Or ( Box < Rule > , Box < Rule > ) ,
104
+ Xor ( Box < Rule > , Box < Rule > ) ,
105
+ Not ( Box < Rule > ) ,
106
+ Lt ( Box < Rule > , Box < Rule > ) ,
107
+ Lte ( Box < Rule > , Box < Rule > ) ,
108
+ Gt ( Box < Rule > , Box < Rule > ) ,
109
+ Gte ( Box < Rule > , Box < Rule > ) ,
110
+ Equals ( Box < Rule > , Box < Rule > ) ,
111
+ NotEquals ( Box < Rule > , Box < Rule > ) ,
112
+ In ( Box < Rule > , Box < Rule > ) ,
113
+ NotIn ( Box < Rule > , Box < Rule > ) ,
114
+ At ( Box < Rule > , Box < Rule > ) ,
115
+ // Note: this is inclusive of the start and end value
116
+ Between ( Box < Rule > , Box < Rule > , Box < Rule > ) ,
117
+ Split ( Box < Rule > , Box < Rule > ) ,
118
+ StartsWith ( Box < Rule > , Box < Rule > ) ,
119
+ EndsWith ( Box < Rule > , Box < Rule > ) ,
120
+ OnlyShowIf ( Box < Rule > ) ,
101
121
Intersects ( Box < Rule > , Box < Rule > ) ,
102
122
Get ( String ) ,
103
123
/// Output variables can be set any number of times by different rules, except `show`
@@ -124,14 +144,82 @@ impl Function {
124
144
Self :: If ( Box :: new ( condition. into ( ) ) , Box :: new ( then. into ( ) ) )
125
145
}
126
146
147
+ pub fn new_if_not ( condition : impl Into < Rule > , then : impl Into < Rule > ) -> Self {
148
+ Self :: IfNot ( Box :: new ( condition. into ( ) ) , Box :: new ( then. into ( ) ) )
149
+ }
150
+
151
+ pub fn new_if_else (
152
+ condition : impl Into < Rule > ,
153
+ then : impl Into < Rule > ,
154
+ otherwise : impl Into < Rule > ,
155
+ ) -> Self {
156
+ Self :: IfElse (
157
+ Box :: new ( condition. into ( ) ) ,
158
+ Box :: new ( then. into ( ) ) ,
159
+ Box :: new ( otherwise. into ( ) ) ,
160
+ )
161
+ }
162
+
127
163
pub fn new_and ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
128
164
Self :: And ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
129
165
}
130
166
167
+ pub fn new_or ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
168
+ Self :: Or ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
169
+ }
170
+
171
+ pub fn new_xor ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
172
+ Self :: Xor ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
173
+ }
174
+
175
+ pub fn new_not ( statement : impl Into < Rule > ) -> Self {
176
+ Self :: Not ( Box :: new ( statement. into ( ) ) )
177
+ }
178
+
131
179
pub fn new_intersects ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
132
180
Self :: Intersects ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
133
181
}
134
182
183
+ pub fn new_in ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
184
+ Self :: In ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
185
+ }
186
+
187
+ pub fn new_not_in ( lhs : impl Into < Rule > , rhs : impl Into < Rule > ) -> Self {
188
+ Self :: NotIn ( Box :: new ( lhs. into ( ) ) , Box :: new ( rhs. into ( ) ) )
189
+ }
190
+
191
+ pub fn new_between (
192
+ value : impl Into < Rule > ,
193
+ start : impl Into < Rule > ,
194
+ end : impl Into < Rule > ,
195
+ ) -> Self {
196
+ Self :: Between (
197
+ Box :: new ( value. into ( ) ) ,
198
+ Box :: new ( start. into ( ) ) ,
199
+ Box :: new ( end. into ( ) ) ,
200
+ )
201
+ }
202
+
203
+ pub fn new_split ( string : impl Into < Rule > , separator : impl Into < Rule > ) -> Self {
204
+ Self :: Split ( Box :: new ( string. into ( ) ) , Box :: new ( separator. into ( ) ) )
205
+ }
206
+
207
+ pub fn new_starts_with ( string : impl Into < Rule > , start : impl Into < Rule > ) -> Self {
208
+ Self :: StartsWith ( Box :: new ( string. into ( ) ) , Box :: new ( start. into ( ) ) )
209
+ }
210
+
211
+ pub fn new_ends_with ( string : impl Into < Rule > , end : impl Into < Rule > ) -> Self {
212
+ Self :: EndsWith ( Box :: new ( string. into ( ) ) , Box :: new ( end. into ( ) ) )
213
+ }
214
+
215
+ pub fn new_at ( array : impl Into < Rule > , position : impl Into < Rule > ) -> Self {
216
+ Self :: At ( Box :: new ( array. into ( ) ) , Box :: new ( position. into ( ) ) )
217
+ }
218
+
219
+ pub fn new_only_show_if ( condition : impl Into < Rule > ) -> Self {
220
+ Self :: OnlyShowIf ( Box :: new ( condition. into ( ) ) )
221
+ }
222
+
135
223
pub fn new_get ( key : & str ) -> Self {
136
224
Self :: Get ( key. to_string ( ) )
137
225
}
@@ -153,6 +241,13 @@ impl Value {
153
241
}
154
242
}
155
243
244
+ pub fn try_string ( self ) -> Result < String , Error > {
245
+ match self {
246
+ Self :: String ( s) => Ok ( s) ,
247
+ _ => Err ( Error :: TypeError ) ,
248
+ }
249
+ }
250
+
156
251
pub fn try_array ( self ) -> Result < Vec < Value > , Error > {
157
252
match self {
158
253
Self :: Array ( array) => Ok ( array) ,
@@ -391,6 +486,28 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
391
486
None
392
487
}
393
488
}
489
+ Function :: IfNot ( first_rule, second_rule) => {
490
+ let eval_if = eval ( input, output, first_rule) ?
491
+ . ok_or ( Error :: TypeError ) ?
492
+ . try_bool ( ) ?;
493
+
494
+ if !eval_if {
495
+ eval ( input, output, second_rule) ?
496
+ } else {
497
+ None
498
+ }
499
+ }
500
+ Function :: IfElse ( first_rule, second_rule, third_rule) => {
501
+ let eval_if = eval ( input, output, first_rule) ?
502
+ . ok_or ( Error :: TypeError ) ?
503
+ . try_bool ( ) ?;
504
+
505
+ if eval_if {
506
+ eval ( input, output, second_rule) ?
507
+ } else {
508
+ eval ( input, output, third_rule) ?
509
+ }
510
+ }
394
511
Function :: And ( first_rule, second_rule) => {
395
512
let a = eval ( input, output, first_rule) ?
396
513
. ok_or ( Error :: TypeError ) ?
@@ -401,6 +518,81 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
401
518
402
519
Some ( Value :: Bool ( a && b) )
403
520
}
521
+ Function :: Or ( first_rule, second_rule) => {
522
+ let a = eval ( input, output, first_rule) ?
523
+ . ok_or ( Error :: TypeError ) ?
524
+ . try_bool ( ) ?;
525
+ let b = eval ( input, output, second_rule) ?
526
+ . ok_or ( Error :: TypeError ) ?
527
+ . try_bool ( ) ?;
528
+
529
+ Some ( Value :: Bool ( a || b) )
530
+ }
531
+ Function :: Xor ( first_rule, second_rule) => {
532
+ let a = eval ( input, output, first_rule) ?
533
+ . ok_or ( Error :: TypeError ) ?
534
+ . try_bool ( ) ?;
535
+ let b = eval ( input, output, second_rule) ?
536
+ . ok_or ( Error :: TypeError ) ?
537
+ . try_bool ( ) ?;
538
+
539
+ Some ( Value :: Bool ( ( a && !b) || ( !a && b) ) )
540
+ }
541
+ Function :: Not ( first_rule) => {
542
+ let a = eval ( input, output, first_rule) ?
543
+ . ok_or ( Error :: TypeError ) ?
544
+ . try_bool ( ) ?;
545
+
546
+ Some ( Value :: Bool ( !a) )
547
+ }
548
+ Function :: Lt ( first_rule, second_rule) => {
549
+ let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
550
+ let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
551
+
552
+ let lhs = BigNum :: try_from ( first_eval) ?;
553
+ let rhs = BigNum :: try_from ( second_eval) ?;
554
+ Some ( Value :: Bool ( lhs. lt ( & rhs) ) )
555
+ }
556
+ Function :: Lte ( first_rule, second_rule) => {
557
+ let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
558
+ let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
559
+
560
+ let lhs = BigNum :: try_from ( first_eval) ?;
561
+ let rhs = BigNum :: try_from ( second_eval) ?;
562
+ Some ( Value :: Bool ( lhs. le ( & rhs) ) )
563
+ }
564
+ Function :: Gt ( first_rule, second_rule) => {
565
+ let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
566
+ let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
567
+
568
+ let lhs = BigNum :: try_from ( first_eval) ?;
569
+ let rhs = BigNum :: try_from ( second_eval) ?;
570
+ Some ( Value :: Bool ( lhs. gt ( & rhs) ) )
571
+ }
572
+ Function :: Gte ( first_rule, second_rule) => {
573
+ let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
574
+ let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
575
+
576
+ let lhs = BigNum :: try_from ( first_eval) ?;
577
+ let rhs = BigNum :: try_from ( second_eval) ?;
578
+ Some ( Value :: Bool ( lhs. ge ( & rhs) ) )
579
+ }
580
+ Function :: Equals ( first_rule, second_rule) => {
581
+ let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
582
+ let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
583
+
584
+ let lhs = BigNum :: try_from ( first_eval) ?;
585
+ let rhs = BigNum :: try_from ( second_eval) ?;
586
+ Some ( Value :: Bool ( lhs. eq ( & rhs) ) )
587
+ }
588
+ Function :: NotEquals ( first_rule, second_rule) => {
589
+ let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
590
+ let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
591
+
592
+ let lhs = BigNum :: try_from ( first_eval) ?;
593
+ let rhs = BigNum :: try_from ( second_eval) ?;
594
+ Some ( Value :: Bool ( lhs. ne ( & rhs) ) )
595
+ }
404
596
Function :: Intersects ( first_rule, second_rule) => {
405
597
let a = eval ( input, output, first_rule) ?
406
598
. ok_or ( Error :: TypeError ) ?
@@ -411,6 +603,94 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
411
603
412
604
Some ( Value :: Bool ( a. iter ( ) . any ( |x| b. contains ( x) ) ) )
413
605
}
606
+ Function :: In ( first_rule, second_rule) => {
607
+ let a = eval ( input, output, first_rule) ?. ok_or ( Error :: TypeError ) ?;
608
+ let b = eval ( input, output, second_rule) ?
609
+ . ok_or ( Error :: TypeError ) ?
610
+ . try_array ( ) ?;
611
+
612
+ Some ( Value :: Bool ( b. contains ( & a) ) )
613
+ }
614
+ Function :: NotIn ( first_rule, second_rule) => {
615
+ let a = eval ( input, output, first_rule) ?. ok_or ( Error :: TypeError ) ?;
616
+ let b = eval ( input, output, second_rule) ?
617
+ . ok_or ( Error :: TypeError ) ?
618
+ . try_array ( ) ?;
619
+
620
+ Some ( Value :: Bool ( !b. contains ( & a) ) )
621
+ }
622
+ Function :: Between ( first_rule, second_rule, third_rule) => {
623
+ let first_eval = first_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
624
+ let second_eval = second_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
625
+ let third_eval = third_rule. eval ( input, output) ?. ok_or ( Error :: TypeError ) ?;
626
+
627
+ let value = BigNum :: try_from ( first_eval) ?;
628
+ let start = BigNum :: try_from ( second_eval) ?;
629
+ let end = BigNum :: try_from ( third_eval) ?;
630
+
631
+ Some ( Value :: Bool ( value. ge ( & start) && value. le ( & end) ) )
632
+ }
633
+ Function :: At ( first_rule, second_rule) => {
634
+ let first_eval = first_rule
635
+ . eval ( input, output) ?
636
+ . ok_or ( Error :: TypeError ) ?
637
+ . try_array ( ) ?;
638
+ let second_eval = second_rule
639
+ . eval ( input, output) ?
640
+ . ok_or ( Error :: TypeError ) ?
641
+ . try_number ( ) ?
642
+ . as_u64 ( )
643
+ . ok_or ( Error :: TypeError ) ?;
644
+ let index = second_eval as usize ;
645
+ let value = & first_eval[ index] ;
646
+ Some ( value. clone ( ) )
647
+ }
648
+ Function :: Split ( first_rule, second_rule) => {
649
+ let first_eval = first_rule
650
+ . eval ( input, output) ?
651
+ . ok_or ( Error :: TypeError ) ?
652
+ . try_string ( ) ?;
653
+ let second_eval = second_rule
654
+ . eval ( input, output) ?
655
+ . ok_or ( Error :: TypeError ) ?
656
+ . try_string ( ) ?;
657
+
658
+ let after_split: Vec < & str > = first_eval. split ( & second_eval) . collect ( ) ;
659
+ let mapped_to_value = after_split
660
+ . into_iter ( )
661
+ . map ( |x| Value :: new_string ( x) )
662
+ . collect ( ) ;
663
+ Some ( Value :: Array ( mapped_to_value) )
664
+ }
665
+ Function :: StartsWith ( first_rule, second_rule) => {
666
+ let first_eval = first_rule
667
+ . eval ( input, output) ?
668
+ . ok_or ( Error :: TypeError ) ?
669
+ . try_string ( ) ?;
670
+ let second_eval = second_rule
671
+ . eval ( input, output) ?
672
+ . ok_or ( Error :: TypeError ) ?
673
+ . try_string ( ) ?;
674
+
675
+ Some ( Value :: Bool ( first_eval. starts_with ( & second_eval) ) )
676
+ }
677
+ Function :: EndsWith ( first_rule, second_rule) => {
678
+ let first_eval = first_rule
679
+ . eval ( input, output) ?
680
+ . ok_or ( Error :: TypeError ) ?
681
+ . try_string ( ) ?;
682
+ let second_eval = second_rule
683
+ . eval ( input, output) ?
684
+ . ok_or ( Error :: TypeError ) ?
685
+ . try_string ( ) ?;
686
+
687
+ Some ( Value :: Bool ( first_eval. ends_with ( & second_eval) ) )
688
+ }
689
+ Function :: OnlyShowIf ( first_rule) => eval (
690
+ input,
691
+ output,
692
+ & Rule :: Function ( Function :: Set ( String :: from ( "show" ) , first_rule. clone ( ) ) ) ,
693
+ ) ?,
414
694
Function :: Set ( key, rule) => {
415
695
// Output variables can be set any number of times by different rules, except `show`
416
696
// if `show` is at any point set to `false`, we stop executing rules and don't show the ad.
0 commit comments