@@ -106,8 +106,11 @@ pub struct PushRuleEvaluator {
106106 /// flag as MSC1767 (extensible events core).
107107 msc3931_enabled : bool ,
108108
109- // If MSC4210 (remove legacy mentions) is enabled.
109+ /// If MSC4210 (remove legacy mentions) is enabled.
110110 msc4210_enabled : bool ,
111+
112+ /// If MSC4306 (thread subscriptions) is enabled.
113+ msc4306_enabled : bool ,
111114}
112115
113116#[ pymethods]
@@ -126,6 +129,7 @@ impl PushRuleEvaluator {
126129 room_version_feature_flags,
127130 msc3931_enabled,
128131 msc4210_enabled,
132+ msc4306_enabled,
129133 ) ) ]
130134 pub fn py_new (
131135 flattened_keys : BTreeMap < String , JsonValue > ,
@@ -138,6 +142,7 @@ impl PushRuleEvaluator {
138142 room_version_feature_flags : Vec < String > ,
139143 msc3931_enabled : bool ,
140144 msc4210_enabled : bool ,
145+ msc4306_enabled : bool ,
141146 ) -> Result < Self , Error > {
142147 let body = match flattened_keys. get ( "content.body" ) {
143148 Some ( JsonValue :: Value ( SimpleJsonValue :: Str ( s) ) ) => s. clone ( ) . into_owned ( ) ,
@@ -156,6 +161,7 @@ impl PushRuleEvaluator {
156161 room_version_feature_flags,
157162 msc3931_enabled,
158163 msc4210_enabled,
164+ msc4306_enabled,
159165 } )
160166 }
161167
@@ -167,12 +173,19 @@ impl PushRuleEvaluator {
167173 ///
168174 /// Returns the set of actions, if any, that match (filtering out any
169175 /// `dont_notify` and `coalesce` actions).
170- #[ pyo3( signature = ( push_rules, user_id=None , display_name=None ) ) ]
176+ ///
177+ /// msc4306_thread_subscription_state: (Only populated if MSC4306 is enabled)
178+ /// The thread subscription state corresponding to the thread containing this event.
179+ /// - `None` if the event is not in a thread, or if MSC4306 is disabled.
180+ /// - `Some(true)` if the event is in a thread and the user has a subscription for that thread
181+ /// - `Some(false)` if the event is in a thread and the user does NOT have a subscription for that thread
182+ #[ pyo3( signature = ( push_rules, user_id=None , display_name=None , msc4306_thread_subscription_state=None ) ) ]
171183 pub fn run (
172184 & self ,
173185 push_rules : & FilteredPushRules ,
174186 user_id : Option < & str > ,
175187 display_name : Option < & str > ,
188+ msc4306_thread_subscription_state : Option < bool > ,
176189 ) -> Vec < Action > {
177190 ' outer: for ( push_rule, enabled) in push_rules. iter ( ) {
178191 if !enabled {
@@ -204,7 +217,12 @@ impl PushRuleEvaluator {
204217 Condition :: Known ( KnownCondition :: RoomVersionSupports { feature: _ } ) ,
205218 ) ;
206219
207- match self . match_condition ( condition, user_id, display_name) {
220+ match self . match_condition (
221+ condition,
222+ user_id,
223+ display_name,
224+ msc4306_thread_subscription_state,
225+ ) {
208226 Ok ( true ) => { }
209227 Ok ( false ) => continue ' outer,
210228 Err ( err) => {
@@ -237,14 +255,20 @@ impl PushRuleEvaluator {
237255 }
238256
239257 /// Check if the given condition matches.
240- #[ pyo3( signature = ( condition, user_id=None , display_name=None ) ) ]
258+ #[ pyo3( signature = ( condition, user_id=None , display_name=None , msc4306_thread_subscription_state= None ) ) ]
241259 fn matches (
242260 & self ,
243261 condition : Condition ,
244262 user_id : Option < & str > ,
245263 display_name : Option < & str > ,
264+ msc4306_thread_subscription_state : Option < bool > ,
246265 ) -> bool {
247- match self . match_condition ( & condition, user_id, display_name) {
266+ match self . match_condition (
267+ & condition,
268+ user_id,
269+ display_name,
270+ msc4306_thread_subscription_state,
271+ ) {
248272 Ok ( true ) => true ,
249273 Ok ( false ) => false ,
250274 Err ( err) => {
@@ -262,6 +286,7 @@ impl PushRuleEvaluator {
262286 condition : & Condition ,
263287 user_id : Option < & str > ,
264288 display_name : Option < & str > ,
289+ msc4306_thread_subscription_state : Option < bool > ,
265290 ) -> Result < bool , Error > {
266291 let known_condition = match condition {
267292 Condition :: Known ( known) => known,
@@ -393,6 +418,13 @@ impl PushRuleEvaluator {
393418 && self . room_version_feature_flags . contains ( & flag)
394419 }
395420 }
421+ KnownCondition :: Msc4306ThreadSubscription { subscribed } => {
422+ if !self . msc4306_enabled {
423+ false
424+ } else {
425+ msc4306_thread_subscription_state == Some ( * subscribed)
426+ }
427+ }
396428 } ;
397429
398430 Ok ( result)
@@ -536,10 +568,11 @@ fn push_rule_evaluator() {
536568 vec ! [ ] ,
537569 true ,
538570 false ,
571+ false ,
539572 )
540573 . unwrap ( ) ;
541574
542- let result = evaluator. run ( & FilteredPushRules :: default ( ) , None , Some ( "bob" ) ) ;
575+ let result = evaluator. run ( & FilteredPushRules :: default ( ) , None , Some ( "bob" ) , None ) ;
543576 assert_eq ! ( result. len( ) , 3 ) ;
544577}
545578
@@ -566,6 +599,7 @@ fn test_requires_room_version_supports_condition() {
566599 flags,
567600 true ,
568601 false ,
602+ false ,
569603 )
570604 . unwrap ( ) ;
571605
@@ -575,6 +609,7 @@ fn test_requires_room_version_supports_condition() {
575609 & FilteredPushRules :: default ( ) ,
576610 Some ( "@bob:example.org" ) ,
577611 None ,
612+ None ,
578613 ) ;
579614 assert_eq ! ( result. len( ) , 3 ) ;
580615
@@ -593,7 +628,17 @@ fn test_requires_room_version_supports_condition() {
593628 } ;
594629 let rules = PushRules :: new ( vec ! [ custom_rule] ) ;
595630 result = evaluator. run (
596- & FilteredPushRules :: py_new ( rules, BTreeMap :: new ( ) , true , false , true , false , false ) ,
631+ & FilteredPushRules :: py_new (
632+ rules,
633+ BTreeMap :: new ( ) ,
634+ true ,
635+ false ,
636+ true ,
637+ false ,
638+ false ,
639+ false ,
640+ ) ,
641+ None ,
597642 None ,
598643 None ,
599644 ) ;
0 commit comments