@@ -17,16 +17,19 @@ use std::{
17
17
collections:: { btree_map, BTreeMap } ,
18
18
} ;
19
19
20
- use ruma:: { OwnedRoomId , RoomId } ;
20
+ use ruma:: { events :: StaticEventTypePart , OwnedRoomId , RoomId } ;
21
21
22
22
use super :: { EventHandlerFn , EventHandlerHandle , EventHandlerWrapper , HandlerKind } ;
23
23
24
24
#[ derive( Default ) ]
25
25
pub ( super ) struct EventHandlerMaps {
26
26
by_kind : BTreeMap < HandlerKind , Vec < EventHandlerWrapper > > ,
27
27
by_kind_type : BTreeMap < KindTypeWrap , Vec < EventHandlerWrapper > > ,
28
+ by_kind_type_prefix : BTreeMap < HandlerKind , BTreeMap < & ' static str , Vec < EventHandlerWrapper > > > ,
28
29
by_kind_roomid : BTreeMap < KindRoomId , Vec < EventHandlerWrapper > > ,
29
30
by_kind_type_roomid : BTreeMap < KindTypeRoomIdWrap , Vec < EventHandlerWrapper > > ,
31
+ by_kind_type_prefix_roomid :
32
+ BTreeMap < KindRoomId , BTreeMap < & ' static str , Vec < EventHandlerWrapper > > > ,
30
33
}
31
34
32
35
impl EventHandlerMaps {
@@ -40,12 +43,27 @@ impl EventHandlerMaps {
40
43
Key :: KindType ( key) => {
41
44
self . by_kind_type . entry ( key) . or_default ( ) . push ( wrapper) ;
42
45
}
46
+ Key :: KindTypePrefix ( outer_key, inner_key) => {
47
+ self . by_kind_type_prefix
48
+ . entry ( outer_key)
49
+ . or_default ( )
50
+ . entry ( inner_key)
51
+ . or_default ( )
52
+ . push ( wrapper) ;
53
+ }
43
54
Key :: KindRoomId ( key) => {
44
55
self . by_kind_roomid . entry ( key) . or_default ( ) . push ( wrapper) ;
45
56
}
46
57
Key :: KindTypeRoomId ( key) => {
47
58
self . by_kind_type_roomid . entry ( key) . or_default ( ) . push ( wrapper)
48
59
}
60
+ Key :: KindTypePrefixRoomId ( outer_key, inner_key) => self
61
+ . by_kind_type_prefix_roomid
62
+ . entry ( outer_key)
63
+ . or_default ( )
64
+ . entry ( inner_key)
65
+ . or_default ( )
66
+ . push ( wrapper) ,
49
67
}
50
68
}
51
69
@@ -61,7 +79,16 @@ impl EventHandlerMaps {
61
79
let kind_type_kv = self
62
80
. by_kind_type
63
81
. get_key_value ( & KindType { ev_kind, ev_type } )
64
- . map ( |( key, handlers) | ( Some ( key. 0 . ev_type ) , handlers) ) ;
82
+ . map ( |( key, handlers) | ( Some ( StaticEventTypePart :: Full ( key. 0 . ev_type ) ) , handlers) ) ;
83
+ let kind_type_prefix_kv = self
84
+ . by_kind_type_prefix
85
+ . get_key_value ( & ev_kind)
86
+ . and_then ( |( _, inner_map) | {
87
+ inner_map. iter ( ) . find ( |( ev_type_prefix, _) | ev_type. starts_with ( * * ev_type_prefix) )
88
+ } )
89
+ . map ( |( ev_type_prefix, handlers) | {
90
+ ( Some ( StaticEventTypePart :: Prefix ( ev_type_prefix) ) , handlers)
91
+ } ) ;
65
92
let maybe_roomid_kvs = room_id
66
93
. map ( |r_id| {
67
94
let room_id = r_id. to_owned ( ) ;
@@ -74,15 +101,33 @@ impl EventHandlerMaps {
74
101
let kind_type_roomid_kv = self
75
102
. by_kind_type_roomid
76
103
. get_key_value ( & KindTypeRoomId { ev_kind, ev_type, room_id } )
77
- . map ( |( key, handlers) | ( Some ( key. 0 . ev_type ) , handlers) ) ;
104
+ . map ( |( key, handlers) | {
105
+ ( Some ( StaticEventTypePart :: Full ( key. 0 . ev_type ) ) , handlers)
106
+ } ) ;
78
107
79
- [ kind_roomid_kv, kind_type_roomid_kv]
108
+ let room_id = r_id. to_owned ( ) ;
109
+ let kind_type_prefix_roomid_kv = self
110
+ . by_kind_type_prefix_roomid
111
+ . get_key_value ( & KindRoomId { ev_kind, room_id } )
112
+ . and_then ( |( _, inner_map) | {
113
+ inner_map
114
+ . iter ( )
115
+ . find ( |( ev_type_prefix, _) | ev_type. starts_with ( * * ev_type_prefix) )
116
+ } )
117
+ . map ( |( ev_type_prefix, handlers) | {
118
+ ( Some ( StaticEventTypePart :: Prefix ( ev_type_prefix) ) , handlers)
119
+ } ) ;
120
+
121
+ [ kind_roomid_kv, kind_type_roomid_kv, kind_type_prefix_roomid_kv]
80
122
} )
81
123
. into_iter ( )
82
124
. flatten ( ) ;
83
125
84
- [ kind_kv, kind_type_kv] . into_iter ( ) . chain ( maybe_roomid_kvs) . flatten ( ) . flat_map (
85
- move |( ev_type, handlers) | {
126
+ [ kind_kv, kind_type_kv, kind_type_prefix_kv]
127
+ . into_iter ( )
128
+ . chain ( maybe_roomid_kvs)
129
+ . flatten ( )
130
+ . flat_map ( move |( ev_type, handlers) | {
86
131
handlers. iter ( ) . map ( move |wrap| {
87
132
let handle = EventHandlerHandle {
88
133
ev_kind,
@@ -93,8 +138,7 @@ impl EventHandlerMaps {
93
138
94
139
( handle, & * wrap. handler_fn )
95
140
} )
96
- } ,
97
- )
141
+ } )
98
142
}
99
143
100
144
pub fn remove ( & mut self , handle : EventHandlerHandle ) {
@@ -113,6 +157,21 @@ impl EventHandlerMaps {
113
157
}
114
158
}
115
159
}
160
+ fn remove_nested_entry < K1 : Ord , K2 : Ord > (
161
+ map : & mut BTreeMap < K1 , BTreeMap < K2 , Vec < EventHandlerWrapper > > > ,
162
+ outer_key : K1 ,
163
+ inner_key : K2 ,
164
+ handler_id : u64 ,
165
+ ) {
166
+ if let btree_map:: Entry :: Occupied ( mut o) = map. entry ( outer_key) {
167
+ let v = o. get_mut ( ) ;
168
+ remove_entry ( v, inner_key, handler_id) ;
169
+
170
+ if v. is_empty ( ) {
171
+ o. remove ( ) ;
172
+ }
173
+ }
174
+ }
116
175
117
176
let handler_id = handle. handler_id ;
118
177
match Key :: new ( handle) {
@@ -122,12 +181,28 @@ impl EventHandlerMaps {
122
181
Key :: KindType ( key) => {
123
182
remove_entry ( & mut self . by_kind_type , key, handler_id) ;
124
183
}
184
+ Key :: KindTypePrefix ( outer_key, inner_key) => {
185
+ remove_nested_entry (
186
+ & mut self . by_kind_type_prefix ,
187
+ outer_key,
188
+ inner_key,
189
+ handler_id,
190
+ ) ;
191
+ }
125
192
Key :: KindRoomId ( key) => {
126
193
remove_entry ( & mut self . by_kind_roomid , key, handler_id) ;
127
194
}
128
195
Key :: KindTypeRoomId ( key) => {
129
196
remove_entry ( & mut self . by_kind_type_roomid , key, handler_id) ;
130
197
}
198
+ Key :: KindTypePrefixRoomId ( outer_key, inner_key) => {
199
+ remove_nested_entry (
200
+ & mut self . by_kind_type_prefix_roomid ,
201
+ outer_key,
202
+ inner_key,
203
+ handler_id,
204
+ ) ;
205
+ }
131
206
}
132
207
}
133
208
@@ -140,21 +215,38 @@ impl EventHandlerMaps {
140
215
enum Key {
141
216
Kind ( HandlerKind ) ,
142
217
KindType ( KindTypeWrap ) ,
218
+ KindTypePrefix ( HandlerKind , & ' static str ) ,
143
219
KindRoomId ( KindRoomId ) ,
144
220
KindTypeRoomId ( KindTypeRoomIdWrap ) ,
221
+ KindTypePrefixRoomId ( KindRoomId , & ' static str ) ,
145
222
}
146
223
147
224
impl Key {
148
225
fn new ( handle : EventHandlerHandle ) -> Self {
149
226
let EventHandlerHandle { ev_kind, ev_type, room_id, .. } = handle;
150
227
match ( ev_type, room_id) {
151
228
( None , None ) => Key :: Kind ( ev_kind) ,
152
- ( Some ( ev_type) , None ) => Key :: KindType ( KindTypeWrap ( KindType { ev_kind, ev_type } ) ) ,
229
+ ( Some ( ev_type) , None ) => match ev_type {
230
+ StaticEventTypePart :: Full ( ev_type) => {
231
+ Key :: KindType ( KindTypeWrap ( KindType { ev_kind, ev_type } ) )
232
+ }
233
+ StaticEventTypePart :: Prefix ( ev_type_prefix) => {
234
+ Key :: KindTypePrefix ( ev_kind, ev_type_prefix)
235
+ }
236
+ } ,
153
237
( None , Some ( room_id) ) => Key :: KindRoomId ( KindRoomId { ev_kind, room_id } ) ,
154
- ( Some ( ev_type) , Some ( room_id) ) => {
155
- let inner = KindTypeRoomId { ev_kind, ev_type, room_id } ;
156
- Key :: KindTypeRoomId ( KindTypeRoomIdWrap ( inner) )
157
- }
238
+ ( Some ( ev_type) , Some ( room_id) ) => match ev_type {
239
+ StaticEventTypePart :: Full ( ev_type) => {
240
+ Key :: KindTypeRoomId ( KindTypeRoomIdWrap ( KindTypeRoomId {
241
+ ev_kind,
242
+ ev_type,
243
+ room_id,
244
+ } ) )
245
+ }
246
+ StaticEventTypePart :: Prefix ( ev_type_prefix) => {
247
+ Key :: KindTypePrefixRoomId ( KindRoomId { ev_kind, room_id } , ev_type_prefix)
248
+ }
249
+ } ,
158
250
}
159
251
}
160
252
}
0 commit comments