@@ -108,27 +108,31 @@ pub enum LoopCtrl {
108
108
/// All of the state is held in an `Arc` so the `Client` can be cloned freely.
109
109
#[ derive( Clone ) ]
110
110
pub struct Client {
111
+ pub ( crate ) inner : Arc < ClientInner > ,
112
+ }
113
+
114
+ pub ( crate ) struct ClientInner {
111
115
/// The URL of the homeserver to connect to.
112
116
homeserver : Arc < RwLock < Url > > ,
113
117
/// The underlying HTTP client.
114
118
http_client : HttpClient ,
115
119
/// User session data.
116
- pub ( crate ) base_client : BaseClient ,
120
+ base_client : BaseClient ,
117
121
/// Locks making sure we only have one group session sharing request in
118
122
/// flight per room.
119
123
#[ cfg( feature = "encryption" ) ]
120
- pub ( crate ) group_session_locks : Arc < DashMap < RoomId , Arc < Mutex < ( ) > > > > ,
124
+ pub ( crate ) group_session_locks : DashMap < RoomId , Arc < Mutex < ( ) > > > ,
121
125
#[ cfg( feature = "encryption" ) ]
122
126
/// Lock making sure we're only doing one key claim request at a time.
123
- pub ( crate ) key_claim_lock : Arc < Mutex < ( ) > > ,
124
- pub ( crate ) members_request_locks : Arc < DashMap < RoomId , Arc < Mutex < ( ) > > > > ,
125
- pub ( crate ) typing_notice_times : Arc < DashMap < RoomId , Instant > > ,
127
+ pub ( crate ) key_claim_lock : Mutex < ( ) > ,
128
+ pub ( crate ) members_request_locks : DashMap < RoomId , Arc < Mutex < ( ) > > > ,
129
+ pub ( crate ) typing_notice_times : DashMap < RoomId , Instant > ,
126
130
/// Event handlers. See `register_event_handler`.
127
- event_handlers : Arc < RwLock < EventHandlerMap > > ,
131
+ event_handlers : RwLock < EventHandlerMap > ,
128
132
/// Custom event handler context. See `register_event_handler_context`.
129
- event_handler_data : Arc < StdRwLock < AnyMap > > ,
133
+ event_handler_data : StdRwLock < AnyMap > ,
130
134
/// Notification handlers. See `register_notification_handler`.
131
- notification_handlers : Arc < RwLock < Vec < NotificationHandlerFn > > > ,
135
+ notification_handlers : RwLock < Vec < NotificationHandlerFn > > ,
132
136
/// Whether the client should operate in application service style mode.
133
137
/// This is low-level functionality. For an high-level API check the
134
138
/// `matrix_sdk_appservice` crate.
@@ -141,7 +145,7 @@ pub struct Client {
141
145
/// synchronization, e.g. if we send out a request to create a room, we can
142
146
/// wait for the sync to get the data to fetch a room object from the state
143
147
/// store.
144
- pub ( crate ) sync_beat : Arc < event_listener:: Event > ,
148
+ pub ( crate ) sync_beat : event_listener:: Event ,
145
149
}
146
150
147
151
#[ cfg( not( tarpaulin_include) ) ]
@@ -185,7 +189,7 @@ impl Client {
185
189
let http_client =
186
190
HttpClient :: new ( client, homeserver. clone ( ) , session, config. request_config ) ;
187
191
188
- Ok ( Self {
192
+ let inner = Arc :: new ( ClientInner {
189
193
homeserver,
190
194
http_client,
191
195
base_client,
@@ -200,8 +204,10 @@ impl Client {
200
204
notification_handlers : Default :: default ( ) ,
201
205
appservice_mode : config. appservice_mode ,
202
206
use_discovery_response : config. use_discovery_response ,
203
- sync_beat : event_listener:: Event :: new ( ) . into ( ) ,
204
- } )
207
+ sync_beat : event_listener:: Event :: new ( ) ,
208
+ } ) ;
209
+
210
+ Ok ( Self { inner } )
205
211
}
206
212
207
213
/// Create a new [`Client`] using homeserver auto discovery.
@@ -267,6 +273,24 @@ impl Client {
267
273
Ok ( client)
268
274
}
269
275
276
+ pub ( crate ) fn base_client ( & self ) -> & BaseClient {
277
+ & self . inner . base_client
278
+ }
279
+
280
+ #[ cfg( feature = "encryption" ) ]
281
+ pub ( crate ) async fn olm_machine ( & self ) -> Option < matrix_sdk_base:: crypto:: OlmMachine > {
282
+ self . base_client ( ) . olm_machine ( ) . await
283
+ }
284
+
285
+ #[ cfg( feature = "encryption" ) ]
286
+ pub ( crate ) async fn mark_request_as_sent (
287
+ & self ,
288
+ request_id : & matrix_sdk_base:: uuid:: Uuid ,
289
+ response : impl Into < matrix_sdk_base:: crypto:: IncomingResponse < ' _ > > ,
290
+ ) -> Result < ( ) , matrix_sdk_base:: Error > {
291
+ self . base_client ( ) . mark_request_as_sent ( request_id, response) . await
292
+ }
293
+
270
294
fn homeserver_from_user_id ( user_id : & UserId ) -> Result < Url > {
271
295
let homeserver = format ! ( "https://{}" , user_id. server_name( ) ) ;
272
296
#[ allow( unused_mut) ]
@@ -289,7 +313,7 @@ impl Client {
289
313
///
290
314
/// * `homeserver_url` - The new URL to use.
291
315
pub async fn set_homeserver ( & self , homeserver_url : Url ) {
292
- let mut homeserver = self . homeserver . write ( ) . await ;
316
+ let mut homeserver = self . inner . homeserver . write ( ) . await ;
293
317
* homeserver = homeserver_url;
294
318
}
295
319
@@ -323,23 +347,23 @@ impl Client {
323
347
324
348
/// Is the client logged in.
325
349
pub async fn logged_in ( & self ) -> bool {
326
- self . base_client . logged_in ( ) . await
350
+ self . inner . base_client . logged_in ( ) . await
327
351
}
328
352
329
353
/// The Homeserver of the client.
330
354
pub async fn homeserver ( & self ) -> Url {
331
- self . homeserver . read ( ) . await . clone ( )
355
+ self . inner . homeserver . read ( ) . await . clone ( )
332
356
}
333
357
334
358
/// Get the user id of the current owner of the client.
335
359
pub async fn user_id ( & self ) -> Option < UserId > {
336
- let session = self . base_client . session ( ) . read ( ) . await ;
360
+ let session = self . inner . base_client . session ( ) . read ( ) . await ;
337
361
session. as_ref ( ) . cloned ( ) . map ( |s| s. user_id )
338
362
}
339
363
340
364
/// Get the device id that identifies the current session.
341
365
pub async fn device_id ( & self ) -> Option < DeviceIdBox > {
342
- let session = self . base_client . session ( ) . read ( ) . await ;
366
+ let session = self . inner . base_client . session ( ) . read ( ) . await ;
343
367
session. as_ref ( ) . map ( |s| s. device_id . clone ( ) )
344
368
}
345
369
@@ -350,7 +374,7 @@ impl Client {
350
374
/// Can be used with [`Client::restore_login`] to restore a previously
351
375
/// logged in session.
352
376
pub async fn session ( & self ) -> Option < Session > {
353
- self . base_client . session ( ) . read ( ) . await . clone ( )
377
+ self . inner . base_client . session ( ) . read ( ) . await . clone ( )
354
378
}
355
379
356
380
/// Fetches the display name of the owner of the client.
@@ -468,7 +492,7 @@ impl Client {
468
492
469
493
/// Get a reference to the store.
470
494
pub fn store ( & self ) -> & Store {
471
- self . base_client . store ( )
495
+ self . inner . base_client . store ( )
472
496
}
473
497
474
498
/// Sets the mxc avatar url of the client's owner. The avatar gets unset if
@@ -610,34 +634,39 @@ impl Client {
610
634
<H :: Future as Future >:: Output : EventHandlerResult ,
611
635
{
612
636
let event_type = H :: ID . 1 ;
613
- self . event_handlers . write ( ) . await . entry ( H :: ID ) . or_default ( ) . push ( Box :: new ( move |data| {
614
- let maybe_fut = serde_json:: from_str ( data. raw . get ( ) )
615
- . map ( |ev| handler. clone ( ) . handle_event ( ev, data) ) ;
616
-
617
- Box :: pin ( async move {
618
- match maybe_fut {
619
- Ok ( Some ( fut) ) => {
620
- fut. await . print_error ( event_type) ;
621
- }
622
- Ok ( None ) => {
623
- error ! ( "Event handler for {} has an invalid context argument" , event_type) ;
624
- }
625
- Err ( e) => {
626
- warn ! (
627
- "Failed to deserialize `{}` event, skipping event handler.\n \
637
+ self . inner . event_handlers . write ( ) . await . entry ( H :: ID ) . or_default ( ) . push ( Box :: new (
638
+ move |data| {
639
+ let maybe_fut = serde_json:: from_str ( data. raw . get ( ) )
640
+ . map ( |ev| handler. clone ( ) . handle_event ( ev, data) ) ;
641
+
642
+ Box :: pin ( async move {
643
+ match maybe_fut {
644
+ Ok ( Some ( fut) ) => {
645
+ fut. await . print_error ( event_type) ;
646
+ }
647
+ Ok ( None ) => {
648
+ error ! (
649
+ "Event handler for {} has an invalid context argument" ,
650
+ event_type
651
+ ) ;
652
+ }
653
+ Err ( e) => {
654
+ warn ! (
655
+ "Failed to deserialize `{}` event, skipping event handler.\n \
628
656
Deserialization error: {}",
629
- event_type, e,
630
- ) ;
657
+ event_type, e,
658
+ ) ;
659
+ }
631
660
}
632
- }
633
- } )
634
- } ) ) ;
661
+ } )
662
+ } ,
663
+ ) ) ;
635
664
636
665
self
637
666
}
638
667
639
668
pub ( crate ) async fn event_handlers ( & self ) -> RwLockReadGuard < ' _ , EventHandlerMap > {
640
- self . event_handlers . read ( ) . await
669
+ self . inner . event_handlers . read ( ) . await
641
670
}
642
671
643
672
/// Add an arbitrary value for use as event handler context.
@@ -681,15 +710,15 @@ impl Client {
681
710
where
682
711
T : Clone + Send + Sync + ' static ,
683
712
{
684
- self . event_handler_data . write ( ) . unwrap ( ) . insert ( ctx) ;
713
+ self . inner . event_handler_data . write ( ) . unwrap ( ) . insert ( ctx) ;
685
714
self
686
715
}
687
716
688
717
pub ( crate ) fn event_handler_context < T > ( & self ) -> Option < T >
689
718
where
690
719
T : Clone + Send + Sync + ' static ,
691
720
{
692
- let map = self . event_handler_data . read ( ) . unwrap ( ) ;
721
+ let map = self . inner . event_handler_data . read ( ) . unwrap ( ) ;
693
722
map. get :: < T > ( ) . cloned ( )
694
723
}
695
724
@@ -703,7 +732,7 @@ impl Client {
703
732
H : Fn ( Notification , room:: Room , Client ) -> Fut + Send + Sync + ' static ,
704
733
Fut : Future < Output = ( ) > + Send + ' static ,
705
734
{
706
- self . notification_handlers . write ( ) . await . push ( Box :: new (
735
+ self . inner . notification_handlers . write ( ) . await . push ( Box :: new (
707
736
move |notification, room, client| Box :: pin ( ( handler) ( notification, room, client) ) ,
708
737
) ) ;
709
738
@@ -713,7 +742,7 @@ impl Client {
713
742
pub ( crate ) async fn notification_handlers (
714
743
& self ,
715
744
) -> RwLockReadGuard < ' _ , Vec < NotificationHandlerFn > > {
716
- self . notification_handlers . read ( ) . await
745
+ self . inner . notification_handlers . read ( ) . await
717
746
}
718
747
719
748
/// Get all the rooms the client knows about.
@@ -1183,15 +1212,15 @@ impl Client {
1183
1212
///
1184
1213
/// * `response` - A successful login response.
1185
1214
async fn receive_login_response ( & self , response : & login:: Response ) -> Result < ( ) > {
1186
- if self . use_discovery_response {
1215
+ if self . inner . use_discovery_response {
1187
1216
if let Some ( well_known) = & response. well_known {
1188
1217
if let Ok ( homeserver) = Url :: parse ( & well_known. homeserver . base_url ) {
1189
1218
self . set_homeserver ( homeserver) . await ;
1190
1219
}
1191
1220
}
1192
1221
}
1193
1222
1194
- self . base_client . receive_login_response ( response) . await ?;
1223
+ self . inner . base_client . receive_login_response ( response) . await ?;
1195
1224
1196
1225
Ok ( ( ) )
1197
1226
}
@@ -1254,7 +1283,7 @@ impl Client {
1254
1283
///
1255
1284
/// [`login`]: #method.login
1256
1285
pub async fn restore_login ( & self , session : Session ) -> Result < ( ) > {
1257
- Ok ( self . base_client . restore_login ( session) . await ?)
1286
+ Ok ( self . inner . base_client . restore_login ( session) . await ?)
1258
1287
}
1259
1288
1260
1289
/// Register a user to the server.
@@ -1301,8 +1330,8 @@ impl Client {
1301
1330
let homeserver = self . homeserver ( ) . await ;
1302
1331
info ! ( "Registering to {}" , homeserver) ;
1303
1332
1304
- let config = if self . appservice_mode {
1305
- Some ( self . http_client . request_config . force_auth ( ) )
1333
+ let config = if self . inner . appservice_mode {
1334
+ Some ( self . inner . http_client . request_config . force_auth ( ) )
1306
1335
} else {
1307
1336
None
1308
1337
} ;
@@ -1367,14 +1396,14 @@ impl Client {
1367
1396
filter_name : & str ,
1368
1397
definition : FilterDefinition < ' _ > ,
1369
1398
) -> Result < String > {
1370
- if let Some ( filter) = self . base_client . get_filter ( filter_name) . await ? {
1399
+ if let Some ( filter) = self . inner . base_client . get_filter ( filter_name) . await ? {
1371
1400
Ok ( filter)
1372
1401
} else {
1373
1402
let user_id = self . user_id ( ) . await . ok_or ( Error :: AuthenticationRequired ) ?;
1374
1403
let request = FilterUploadRequest :: new ( & user_id, definition) ;
1375
1404
let response = self . send ( request, None ) . await ?;
1376
1405
1377
- self . base_client . receive_filter_upload ( filter_name, & response) . await ?;
1406
+ self . inner . base_client . receive_filter_upload ( filter_name, & response) . await ?;
1378
1407
1379
1408
Ok ( response. filter_id )
1380
1409
}
@@ -1586,8 +1615,8 @@ impl Client {
1586
1615
content_type: Some ( content_type. essence_str( ) ) ,
1587
1616
} ) ;
1588
1617
1589
- let request_config = self . http_client . request_config . timeout ( timeout) ;
1590
- Ok ( self . http_client . upload ( request, Some ( request_config) ) . await ?)
1618
+ let request_config = self . inner . http_client . request_config . timeout ( timeout) ;
1619
+ Ok ( self . inner . http_client . upload ( request, Some ( request_config) ) . await ?)
1591
1620
}
1592
1621
1593
1622
/// Send an arbitrary request to the server, without updating client state.
@@ -1639,7 +1668,7 @@ impl Client {
1639
1668
Request : OutgoingRequest + Debug ,
1640
1669
HttpError : From < FromHttpResponseError < Request :: EndpointError > > ,
1641
1670
{
1642
- Ok ( self . http_client . send ( request, config) . await ?)
1671
+ Ok ( self . inner . http_client . send ( request, config) . await ?)
1643
1672
}
1644
1673
1645
1674
/// Get information of all our own devices.
@@ -1832,9 +1861,9 @@ impl Client {
1832
1861
timeout: sync_settings. timeout,
1833
1862
} ) ;
1834
1863
1835
- let request_config = self . http_client . request_config . timeout (
1864
+ let request_config = self . inner . http_client . request_config . timeout (
1836
1865
sync_settings. timeout . unwrap_or_else ( || Duration :: from_secs ( 0 ) )
1837
- + self . http_client . request_config . timeout ,
1866
+ + self . inner . http_client . request_config . timeout ,
1838
1867
) ;
1839
1868
1840
1869
let response = self . send ( request, Some ( request_config) ) . await ?;
@@ -1845,7 +1874,7 @@ impl Client {
1845
1874
error ! ( error =? e, "Error while sending outgoing E2EE requests" ) ;
1846
1875
} ;
1847
1876
1848
- self . sync_beat . notify ( usize:: MAX ) ;
1877
+ self . inner . sync_beat . notify ( usize:: MAX ) ;
1849
1878
1850
1879
Ok ( response)
1851
1880
}
@@ -2050,7 +2079,7 @@ impl Client {
2050
2079
/// Get the current, if any, sync token of the client.
2051
2080
/// This will be None if the client didn't sync at least once.
2052
2081
pub async fn sync_token ( & self ) -> Option < String > {
2053
- self . base_client . sync_token ( ) . await
2082
+ self . inner . base_client . sync_token ( ) . await
2054
2083
}
2055
2084
2056
2085
/// Get a media file's content.
@@ -2069,7 +2098,7 @@ impl Client {
2069
2098
use_cache : bool ,
2070
2099
) -> Result < Vec < u8 > > {
2071
2100
let content = if use_cache {
2072
- self . base_client . store ( ) . get_media_content ( request) . await ?
2101
+ self . inner . base_client . store ( ) . get_media_content ( request) . await ?
2073
2102
} else {
2074
2103
None
2075
2104
} ;
@@ -2113,7 +2142,7 @@ impl Client {
2113
2142
} ;
2114
2143
2115
2144
if use_cache {
2116
- self . base_client . store ( ) . add_media_content ( request, content. clone ( ) ) . await ?;
2145
+ self . inner . base_client . store ( ) . add_media_content ( request, content. clone ( ) ) . await ?;
2117
2146
}
2118
2147
2119
2148
Ok ( content)
@@ -2126,7 +2155,7 @@ impl Client {
2126
2155
///
2127
2156
/// * `request` - The `MediaRequest` of the content.
2128
2157
pub async fn remove_media_content ( & self , request : & MediaRequest ) -> Result < ( ) > {
2129
- Ok ( self . base_client . store ( ) . remove_media_content ( request) . await ?)
2158
+ Ok ( self . inner . base_client . store ( ) . remove_media_content ( request) . await ?)
2130
2159
}
2131
2160
2132
2161
/// Delete all the media content corresponding to the given
@@ -2136,7 +2165,7 @@ impl Client {
2136
2165
///
2137
2166
/// * `uri` - The `MxcUri` of the files.
2138
2167
pub async fn remove_media_content_for_uri ( & self , uri : & MxcUri ) -> Result < ( ) > {
2139
- Ok ( self . base_client . store ( ) . remove_media_content_for_uri ( uri) . await ?)
2168
+ Ok ( self . inner . base_client . store ( ) . remove_media_content_for_uri ( uri) . await ?)
2140
2169
}
2141
2170
2142
2171
/// Get the file of the given media event content.
@@ -2655,7 +2684,7 @@ pub(crate) mod test {
2655
2684
. add_state_event ( EventsJson :: PowerLevels )
2656
2685
. build_sync_response ( ) ;
2657
2686
2658
- client. base_client . receive_sync_response ( response) . await . unwrap ( ) ;
2687
+ client. inner . base_client . receive_sync_response ( response) . await . unwrap ( ) ;
2659
2688
let room_id = room_id ! ( "!SVkFJHzfwvuaIEawgC:localhost" ) ;
2660
2689
2661
2690
assert_eq ! ( client. homeserver( ) . await , Url :: parse( & mockito:: server_url( ) ) . unwrap( ) ) ;
0 commit comments