Skip to content

Commit f59d47f

Browse files
committed
benjamin's review; let's squash this MR
1 parent d0048e7 commit f59d47f

File tree

9 files changed

+98
-110
lines changed

9 files changed

+98
-110
lines changed

bindings/matrix-sdk-ffi/src/client.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,7 @@ impl Client {
10271027
&self,
10281028
room_id: String,
10291029
via_servers: Vec<String>,
1030-
) -> Result<Arc<RoomPreview>, ClientError> {
1030+
) -> Result<RoomPreview, ClientError> {
10311031
let room_id = RoomId::parse(&room_id).context("room_id is not a valid room id")?;
10321032

10331033
let via_servers = via_servers
@@ -1040,26 +1040,26 @@ impl Client {
10401040
// rustc win that one fight.
10411041
let room_id: &RoomId = &room_id;
10421042

1043-
let sdk_room_preview = self.inner.get_room_preview(room_id.into(), via_servers).await?;
1043+
let room_preview = self.inner.get_room_preview(room_id.into(), via_servers).await?;
10441044

1045-
Ok(Arc::new(RoomPreview::from_sdk(sdk_room_preview)))
1045+
Ok(RoomPreview::new(self.inner.clone(), room_preview))
10461046
}
10471047

10481048
/// Given a room alias, get the preview of a room, to interact with it.
10491049
pub async fn get_room_preview_from_room_alias(
10501050
&self,
10511051
room_alias: String,
1052-
) -> Result<Arc<RoomPreview>, ClientError> {
1052+
) -> Result<RoomPreview, ClientError> {
10531053
let room_alias =
10541054
RoomAliasId::parse(&room_alias).context("room_alias is not a valid room alias")?;
10551055

10561056
// The `into()` call below doesn't work if I do `(&room_id).into()`, so I let
10571057
// rustc win that one fight.
10581058
let room_alias: &RoomAliasId = &room_alias;
10591059

1060-
let sdk_room_preview = self.inner.get_room_preview(room_alias.into(), Vec::new()).await?;
1060+
let room_preview = self.inner.get_room_preview(room_alias.into(), Vec::new()).await?;
10611061

1062-
Ok(Arc::new(RoomPreview::from_sdk(sdk_room_preview)))
1062+
Ok(RoomPreview::new(self.inner.clone(), room_preview))
10631063
}
10641064

10651065
/// Waits until an at least partially synced room is received, and returns
@@ -1830,6 +1830,12 @@ pub enum JoinRule {
18301830
/// conditions described in a set of [`AllowRule`]s, or they can request
18311831
/// an invite to the room.
18321832
KnockRestricted { rules: Vec<AllowRule> },
1833+
1834+
/// A custom join rule, up for interpretation by the consumer.
1835+
Custom {
1836+
/// The string representation for this custom rule.
1837+
repr: String,
1838+
},
18331839
}
18341840

18351841
/// An allow rule which defines a condition that allows joining a room.
@@ -1857,6 +1863,7 @@ impl TryFrom<JoinRule> for ruma::events::room::join_rules::JoinRule {
18571863
let rules = allow_rules_from(rules)?;
18581864
Ok(Self::KnockRestricted(ruma::events::room::join_rules::Restricted::new(rules)))
18591865
}
1866+
JoinRule::Custom { repr } => Ok(serde_json::from_str(&repr)?),
18601867
}
18611868
}
18621869
}

bindings/matrix-sdk-ffi/src/error.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::{collections::HashMap, fmt, fmt::Display};
22

33
use matrix_sdk::{
44
encryption::CryptoStoreError, event_cache::EventCacheError, oidc::OidcError, reqwest,
5-
room::edit::EditError, room_preview::WrongRoomPreviewState, send_queue::RoomSendQueueError,
6-
HttpError, IdParseError, NotificationSettingsError as SdkNotificationSettingsError,
5+
room::edit::EditError, send_queue::RoomSendQueueError, HttpError, IdParseError,
6+
NotificationSettingsError as SdkNotificationSettingsError,
77
QueueWedgeError as SdkQueueWedgeError, StoreError,
88
};
99
use matrix_sdk_ui::{encryption_sync_service, notification_client, sync_service, timeline};
@@ -155,12 +155,6 @@ impl From<RoomSendQueueError> for ClientError {
155155
}
156156
}
157157

158-
impl From<WrongRoomPreviewState> for ClientError {
159-
fn from(e: WrongRoomPreviewState) -> Self {
160-
Self::new(e)
161-
}
162-
}
163-
164158
/// Bindings version of the sdk type replacing OwnedUserId/DeviceIds with simple
165159
/// String.
166160
///

bindings/matrix-sdk-ffi/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ mod room;
1919
mod room_directory_search;
2020
mod room_info;
2121

22-
#[allow(deprecated)]
2322
mod room_list;
2423
mod room_member;
2524
mod room_preview;

bindings/matrix-sdk-ffi/src/room_list.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
use std::{fmt::Debug, mem::MaybeUninit, ptr::addr_of_mut, sync::Arc, time::Duration};
1+
#![allow(deprecated)]
2+
3+
use std::{
4+
fmt::Debug,
5+
mem::{ManuallyDrop, MaybeUninit},
6+
ptr::addr_of_mut,
7+
sync::Arc,
8+
time::Duration,
9+
};
210

311
use eyeball_im::VectorDiff;
412
use futures_util::{pin_mut, StreamExt, TryFutureExt};
@@ -598,7 +606,14 @@ impl RoomListItem {
598606
///
599607
/// An error will be returned if the room is in a state other than invited
600608
/// or knocked.
601-
async fn preview_room(&self, via: Vec<String>) -> Result<Arc<RoomPreview>, ClientError> {
609+
async fn preview_room(&self, via: Vec<String>) -> Result<RoomPreview, ClientError> {
610+
// Validate parameters first.
611+
let server_names: Vec<OwnedServerName> = via
612+
.into_iter()
613+
.map(|server| ServerName::parse(server).map_err(ClientError::from))
614+
.collect::<Result<_, ClientError>>()?;
615+
616+
// Validate internal room state.
602617
let membership = self.membership();
603618
if !matches!(membership, Membership::Invited | Membership::Knocked) {
604619
return Err(RoomListError::IncorrectRoomMembership {
@@ -608,21 +623,19 @@ impl RoomListItem {
608623
.into());
609624
}
610625

626+
// Do the thing.
611627
let client = self.inner.client();
612628
let (room_or_alias_id, server_names) = if let Some(alias) = self.inner.canonical_alias() {
613629
let room_or_alias_id: OwnedRoomOrAliasId = alias.into();
614630
(room_or_alias_id, Vec::new())
615631
} else {
616632
let room_or_alias_id: OwnedRoomOrAliasId = self.inner.id().to_owned().into();
617-
let server_names: Vec<OwnedServerName> = via
618-
.into_iter()
619-
.map(|server| ServerName::parse(server).map_err(ClientError::from))
620-
.collect::<Result<_, ClientError>>()?;
621633
(room_or_alias_id, server_names)
622634
};
623635

624636
let room_preview = client.get_room_preview(&room_or_alias_id, server_names).await?;
625-
Ok(Arc::new(RoomPreview::from_sdk(room_preview)))
637+
638+
Ok(RoomPreview::new(ManuallyDrop::new(client), room_preview))
626639
}
627640

628641
/// Build a full `Room` FFI object, filling its associated timeline.

bindings/matrix-sdk-ffi/src/room_preview.rs

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,41 @@
1-
use std::sync::Arc;
1+
use std::mem::ManuallyDrop;
22

3-
use matrix_sdk::room_preview::RoomPreview as SdkRoomPreview;
3+
use anyhow::Context as _;
4+
use async_compat::TOKIO1 as RUNTIME;
5+
use matrix_sdk::{room_preview::RoomPreview as SdkRoomPreview, Client};
46
use ruma::space::SpaceRoomJoinRule;
7+
use tracing::warn;
58

69
use crate::{client::JoinRule, error::ClientError, room::Membership};
710

811
/// A room preview for a room. It's intended to be used to represent rooms that
912
/// aren't joined yet.
1013
#[derive(uniffi::Object)]
1114
pub struct RoomPreview {
12-
inner: Arc<SdkRoomPreview>,
15+
inner: SdkRoomPreview,
16+
client: ManuallyDrop<Client>,
17+
}
18+
19+
impl Drop for RoomPreview {
20+
fn drop(&mut self) {
21+
// Dropping the inner OlmMachine must happen within a tokio context
22+
// because deadpool drops sqlite connections in the DB pool on tokio's
23+
// blocking threadpool to avoid blocking async worker threads.
24+
let _guard = RUNTIME.enter();
25+
// SAFETY: self.client is never used again, which is the only requirement
26+
// for ManuallyDrop::drop to be used safely.
27+
unsafe {
28+
ManuallyDrop::drop(&mut self.client);
29+
}
30+
}
1331
}
1432

1533
#[matrix_sdk_ffi_macros::export]
1634
impl RoomPreview {
1735
/// Returns the room info the preview contains.
18-
pub fn info(&self) -> RoomPreviewInfo {
36+
pub fn info(&self) -> Result<RoomPreviewInfo, ClientError> {
1937
let info = &self.inner;
20-
RoomPreviewInfo {
38+
Ok(RoomPreviewInfo {
2139
room_id: info.room_id.to_string(),
2240
canonical_alias: info.canonical_alias.as_ref().map(|alias| alias.to_string()),
2341
name: info.name.clone(),
@@ -27,22 +45,28 @@ impl RoomPreview {
2745
room_type: info.room_type.as_ref().map(|room_type| room_type.to_string()),
2846
is_history_world_readable: info.is_world_readable,
2947
membership: info.state.map(|state| state.into()),
30-
join_rule: info.join_rule.clone().into(),
31-
}
48+
join_rule: info
49+
.join_rule
50+
.clone()
51+
.try_into()
52+
.map_err(|_| anyhow::anyhow!("unhandled SpaceRoomJoinRule kind"))?,
53+
})
3254
}
3355

3456
/// Leave the room if the room preview state is either joined, invited or
3557
/// knocked.
3658
///
3759
/// Will return an error otherwise.
3860
pub async fn leave(&self) -> Result<(), ClientError> {
39-
self.inner.leave().await.map_err(Into::into)
61+
let room =
62+
self.client.get_room(&self.inner.room_id).context("missing room for a room preview")?;
63+
room.leave().await.map_err(Into::into)
4064
}
4165
}
4266

4367
impl RoomPreview {
44-
pub(crate) fn from_sdk(room_preview: SdkRoomPreview) -> Self {
45-
Self { inner: Arc::new(room_preview) }
68+
pub(crate) fn new(client: ManuallyDrop<Client>, inner: SdkRoomPreview) -> Self {
69+
Self { client, inner }
4670
}
4771
}
4872

@@ -71,22 +95,26 @@ pub struct RoomPreviewInfo {
7195
pub join_rule: JoinRule,
7296
}
7397

74-
impl From<SpaceRoomJoinRule> for JoinRule {
75-
fn from(join_rule: SpaceRoomJoinRule) -> Self {
76-
match join_rule {
98+
impl TryFrom<SpaceRoomJoinRule> for JoinRule {
99+
type Error = ();
100+
101+
fn try_from(join_rule: SpaceRoomJoinRule) -> Result<Self, ()> {
102+
Ok(match join_rule {
77103
SpaceRoomJoinRule::Invite => JoinRule::Invite,
78104
SpaceRoomJoinRule::Knock => JoinRule::Knock,
79105
SpaceRoomJoinRule::Private => JoinRule::Private,
80106
SpaceRoomJoinRule::Restricted => JoinRule::Restricted { rules: Vec::new() },
81107
SpaceRoomJoinRule::KnockRestricted => JoinRule::KnockRestricted { rules: Vec::new() },
82108
SpaceRoomJoinRule::Public => JoinRule::Public,
109+
SpaceRoomJoinRule::_Custom(_) => JoinRule::Custom { repr: join_rule.to_string() },
83110
_ => {
84111
// Since we have no way to get the _Custom contents, assume it's private.
85112
// Warning! If new join rules are introduced we may be mapping wrong values
86113
// here, but there's no way to match
87114
// `SpaceRoomJoinRule::_Custom(_)` and have an exhaustive match.
88-
JoinRule::Private
115+
warn!("unhandled SpaceRoomJoinRule: {join_rule}");
116+
return Err(());
89117
}
90-
}
118+
})
91119
}
92120
}

crates/matrix-sdk/src/client/mod.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ use ruma::{
5454
},
5555
filter::{create_filter::v3::Request as FilterUploadRequest, FilterDefinition},
5656
knock::knock_room,
57-
membership::{join_room_by_id, join_room_by_id_or_alias, leave_room},
57+
membership::{join_room_by_id, join_room_by_id_or_alias},
5858
room::create_room,
5959
session::login::v3::DiscoveryInfo,
6060
sync::sync_events,
@@ -1208,13 +1208,6 @@ impl Client {
12081208
Ok(Room::new(self.clone(), base_room))
12091209
}
12101210

1211-
/// Leave a room given its `RoomId`.
1212-
pub async fn leave_room(&self, room_id: &RoomId) -> Result<()> {
1213-
let request = leave_room::v3::Request::new(room_id.to_owned());
1214-
self.send(request, None).await?;
1215-
self.base_client().room_left(room_id).await.map_err(Into::into)
1216-
}
1217-
12181211
/// Search the homeserver's directory of public rooms.
12191212
///
12201213
/// Sends a request to "_matrix/client/r0/publicRooms", returns

crates/matrix-sdk/src/error.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ use serde_json::Error as JsonError;
4545
use thiserror::Error;
4646
use url::ParseError as UrlParseError;
4747

48-
use crate::{
49-
event_cache::EventCacheError, room_preview::WrongRoomPreviewState, store_locks::LockStoreError,
50-
};
48+
use crate::{event_cache::EventCacheError, store_locks::LockStoreError};
5149

5250
/// Result type of the matrix-sdk.
5351
pub type Result<T, E = Error> = std::result::Result<T, E>;
@@ -350,12 +348,6 @@ pub enum Error {
350348
#[error("wrong room state: {0}")]
351349
WrongRoomState(WrongRoomState),
352350

353-
/// Attempted to call a method on a room preview that requires the user to
354-
/// have a specific membership state in the room, but the membership
355-
/// state is different or none.
356-
#[error("wrong room state: {0}")]
357-
WrongRoomPreviewState(WrongRoomPreviewState),
358-
359351
/// Session callbacks have been set multiple times.
360352
#[error("session callbacks have been set multiple times")]
361353
MultipleSessionCallbacks,

0 commit comments

Comments
 (0)