@@ -22,8 +22,8 @@ use regex::Regex;
22
22
23
23
use super :: {
24
24
utils:: { get_glob_matcher, get_localpart_from_id, GlobMatchType } ,
25
- Action , Condition , EventMatchCondition , FilteredPushRules , KnownCondition ,
26
- RelatedEventMatchCondition ,
25
+ Action , Condition , EventMatchCondition , ExactEventMatchCondition , FilteredPushRules ,
26
+ KnownCondition , RelatedEventMatchCondition , SimpleJsonValue ,
27
27
} ;
28
28
29
29
lazy_static ! {
@@ -61,9 +61,9 @@ impl RoomVersionFeatures {
61
61
/// Allows running a set of push rules against a particular event.
62
62
#[ pyclass]
63
63
pub struct PushRuleEvaluator {
64
- /// A mapping of "flattened" keys to string values in the event, e.g.
64
+ /// A mapping of "flattened" keys to simple JSON values in the event, e.g.
65
65
/// includes things like "type" and "content.msgtype".
66
- flattened_keys : BTreeMap < String , String > ,
66
+ flattened_keys : BTreeMap < String , SimpleJsonValue > ,
67
67
68
68
/// The "content.body", if any.
69
69
body : String ,
@@ -87,7 +87,7 @@ pub struct PushRuleEvaluator {
87
87
88
88
/// The related events, indexed by relation type. Flattened in the same manner as
89
89
/// `flattened_keys`.
90
- related_events_flattened : BTreeMap < String , BTreeMap < String , String > > ,
90
+ related_events_flattened : BTreeMap < String , BTreeMap < String , SimpleJsonValue > > ,
91
91
92
92
/// If msc3664, push rules for related events, is enabled.
93
93
related_event_match_enabled : bool ,
@@ -98,6 +98,9 @@ pub struct PushRuleEvaluator {
98
98
/// If MSC3931 (room version feature flags) is enabled. Usually controlled by the same
99
99
/// flag as MSC1767 (extensible events core).
100
100
msc3931_enabled : bool ,
101
+
102
+ /// If MSC3758 (exact_event_match push rule condition) is enabled.
103
+ msc3758_exact_event_match : bool ,
101
104
}
102
105
103
106
#[ pymethods]
@@ -106,22 +109,23 @@ impl PushRuleEvaluator {
106
109
#[ allow( clippy:: too_many_arguments) ]
107
110
#[ new]
108
111
pub fn py_new (
109
- flattened_keys : BTreeMap < String , String > ,
112
+ flattened_keys : BTreeMap < String , SimpleJsonValue > ,
110
113
has_mentions : bool ,
111
114
user_mentions : BTreeSet < String > ,
112
115
room_mention : bool ,
113
116
room_member_count : u64 ,
114
117
sender_power_level : Option < i64 > ,
115
118
notification_power_levels : BTreeMap < String , i64 > ,
116
- related_events_flattened : BTreeMap < String , BTreeMap < String , String > > ,
119
+ related_events_flattened : BTreeMap < String , BTreeMap < String , SimpleJsonValue > > ,
117
120
related_event_match_enabled : bool ,
118
121
room_version_feature_flags : Vec < String > ,
119
122
msc3931_enabled : bool ,
123
+ msc3758_exact_event_match : bool ,
120
124
) -> Result < Self , Error > {
121
- let body = flattened_keys
122
- . get ( "content.body" )
123
- . cloned ( )
124
- . unwrap_or_default ( ) ;
125
+ let body = match flattened_keys. get ( "content.body" ) {
126
+ Some ( SimpleJsonValue :: Str ( s ) ) => s . clone ( ) ,
127
+ _ => String :: new ( ) ,
128
+ } ;
125
129
126
130
Ok ( PushRuleEvaluator {
127
131
flattened_keys,
@@ -136,6 +140,7 @@ impl PushRuleEvaluator {
136
140
related_event_match_enabled,
137
141
room_version_feature_flags,
138
142
msc3931_enabled,
143
+ msc3758_exact_event_match,
139
144
} )
140
145
}
141
146
@@ -252,6 +257,9 @@ impl PushRuleEvaluator {
252
257
KnownCondition :: EventMatch ( event_match) => {
253
258
self . match_event_match ( event_match, user_id) ?
254
259
}
260
+ KnownCondition :: ExactEventMatch ( exact_event_match) => {
261
+ self . match_exact_event_match ( exact_event_match) ?
262
+ }
255
263
KnownCondition :: RelatedEventMatch ( event_match) => {
256
264
self . match_related_event_match ( event_match, user_id) ?
257
265
}
@@ -337,7 +345,9 @@ impl PushRuleEvaluator {
337
345
return Ok ( false ) ;
338
346
} ;
339
347
340
- let haystack = if let Some ( haystack) = self . flattened_keys . get ( & * event_match. key ) {
348
+ let haystack = if let Some ( SimpleJsonValue :: Str ( haystack) ) =
349
+ self . flattened_keys . get ( & * event_match. key )
350
+ {
341
351
haystack
342
352
} else {
343
353
return Ok ( false ) ;
@@ -355,6 +365,27 @@ impl PushRuleEvaluator {
355
365
compiled_pattern. is_match ( haystack)
356
366
}
357
367
368
+ /// Evaluates a `exact_event_match` condition. (MSC3758)
369
+ fn match_exact_event_match (
370
+ & self ,
371
+ exact_event_match : & ExactEventMatchCondition ,
372
+ ) -> Result < bool , Error > {
373
+ // First check if the feature is enabled.
374
+ if !self . msc3758_exact_event_match {
375
+ return Ok ( false ) ;
376
+ }
377
+
378
+ let value = & exact_event_match. value ;
379
+
380
+ let haystack = if let Some ( haystack) = self . flattened_keys . get ( & * exact_event_match. key ) {
381
+ haystack
382
+ } else {
383
+ return Ok ( false ) ;
384
+ } ;
385
+
386
+ Ok ( haystack == & * * value)
387
+ }
388
+
358
389
/// Evaluates a `related_event_match` condition. (MSC3664)
359
390
fn match_related_event_match (
360
391
& self ,
@@ -410,7 +441,7 @@ impl PushRuleEvaluator {
410
441
return Ok ( false ) ;
411
442
} ;
412
443
413
- let haystack = if let Some ( haystack) = event. get ( & * * key) {
444
+ let haystack = if let Some ( SimpleJsonValue :: Str ( haystack) ) = event. get ( & * * key) {
414
445
haystack
415
446
} else {
416
447
return Ok ( false ) ;
@@ -455,7 +486,10 @@ impl PushRuleEvaluator {
455
486
#[ test]
456
487
fn push_rule_evaluator ( ) {
457
488
let mut flattened_keys = BTreeMap :: new ( ) ;
458
- flattened_keys. insert ( "content.body" . to_string ( ) , "foo bar bob hello" . to_string ( ) ) ;
489
+ flattened_keys. insert (
490
+ "content.body" . to_string ( ) ,
491
+ SimpleJsonValue :: Str ( "foo bar bob hello" . to_string ( ) ) ,
492
+ ) ;
459
493
let evaluator = PushRuleEvaluator :: py_new (
460
494
flattened_keys,
461
495
false ,
@@ -468,6 +502,7 @@ fn push_rule_evaluator() {
468
502
true ,
469
503
vec ! [ ] ,
470
504
true ,
505
+ true ,
471
506
)
472
507
. unwrap ( ) ;
473
508
@@ -482,7 +517,10 @@ fn test_requires_room_version_supports_condition() {
482
517
use crate :: push:: { PushRule , PushRules } ;
483
518
484
519
let mut flattened_keys = BTreeMap :: new ( ) ;
485
- flattened_keys. insert ( "content.body" . to_string ( ) , "foo bar bob hello" . to_string ( ) ) ;
520
+ flattened_keys. insert (
521
+ "content.body" . to_string ( ) ,
522
+ SimpleJsonValue :: Str ( "foo bar bob hello" . to_string ( ) ) ,
523
+ ) ;
486
524
let flags = vec ! [ RoomVersionFeatures :: ExtensibleEvents . as_str( ) . to_string( ) ] ;
487
525
let evaluator = PushRuleEvaluator :: py_new (
488
526
flattened_keys,
@@ -496,6 +534,7 @@ fn test_requires_room_version_supports_condition() {
496
534
false ,
497
535
flags,
498
536
true ,
537
+ true ,
499
538
)
500
539
. unwrap ( ) ;
501
540
0 commit comments