From 4628481d0e2c009cc27c8abf4dcf2bb4519d7b9b Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Mon, 26 Sep 2022 19:29:33 +0200 Subject: [PATCH] refactor(bindings): Use UniFFI proc-macro frontend more --- bindings/matrix-sdk-ffi/src/api.udl | 65 +--------- .../src/authentication_service.rs | 13 +- bindings/matrix-sdk-ffi/src/client.rs | 120 +++++++++--------- bindings/matrix-sdk-ffi/src/lib.rs | 12 ++ bindings/matrix-sdk-ffi/src/room.rs | 61 ++++----- .../src/session_verification.rs | 1 + bindings/matrix-sdk-ffi/src/sliding_sync.rs | 33 +++-- 7 files changed, 141 insertions(+), 164 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/api.udl b/bindings/matrix-sdk-ffi/src/api.udl index 8af809d4f..7ddfa1e1e 100644 --- a/bindings/matrix-sdk-ffi/src/api.udl +++ b/bindings/matrix-sdk-ffi/src/api.udl @@ -2,10 +2,7 @@ namespace matrix_sdk_ffi {}; /// Cancels on drop -interface StoppableSpawn { - boolean is_cancelled(); - void cancel(); -}; +interface StoppableSpawn {}; [Error] interface ClientError { @@ -138,44 +135,14 @@ interface SlidingSyncView { StoppableSpawn observe_state(SlidingSyncViewStateObserver observer); StoppableSpawn observe_room_items(SlidingSyncViewRoomItemsObserver observer); - u32? current_room_count(); sequence current_rooms_list(); - - void add_range(u32 from, u32 to); - void reset_ranges(); - void set_range(u32 from, u32 to); }; -interface UnreadNotificationsCount { - boolean has_notifications(); - - u32 highlight_count(); - u32 notification_count(); -}; - -interface SlidingSyncRoom { - string? name(); - string room_id(); - - Room? full_room(); - - boolean? is_dm(); - boolean? is_initial(); - - boolean has_unread_notifications(); - UnreadNotificationsCount unread_notifications(); - - // aliveness - boolean is_loading_more(); - - AnyMessage? latest_room_message(); -}; +interface SlidingSyncRoom {}; interface SlidingSync { void set_observer(SlidingSyncObserver? observer); - StoppableSpawn sync(); - [Throws=ClientError] void subscribe(string room_id, RoomSubscription? settings); [Throws=ClientError] @@ -233,8 +200,6 @@ interface Client { [Throws=ClientError] void restore_login(string restore_token); - void start_sync(u16? timeline_limit); - [Throws=ClientError] string restore_token(); @@ -268,8 +233,6 @@ interface Client { [Throws=ClientError] SlidingSync full_sliding_sync(); - SlidingSyncBuilder sliding_sync(); - [Throws=ClientError] void logout(); }; @@ -285,19 +248,8 @@ enum Membership { }; interface Room { - string id(); - string? name(); - string? topic(); - string? avatar_url(); - Membership membership(); - boolean is_direct(); - boolean is_public(); - boolean is_space(); - boolean is_encrypted(); - boolean is_tombstoned(); - [Throws=ClientError] string display_name(); @@ -372,17 +324,9 @@ enum AuthenticationError { "Generic", }; -interface HomeserverLoginDetails { - string url(); - string? authentication_issuer(); - boolean supports_password_login(); -}; - interface AuthenticationService { constructor(string base_path); - HomeserverLoginDetails? homeserver_details(); - [Throws=AuthenticationError] void configure_homeserver(string server_name); @@ -393,10 +337,7 @@ interface AuthenticationService { Client restore_with_access_token(string token, string device_id); }; -interface SessionVerificationEmoji { - string symbol(); - string description(); -}; +interface SessionVerificationEmoji {}; callback interface SessionVerificationControllerDelegate { void did_receive_verification_data(sequence data); diff --git a/bindings/matrix-sdk-ffi/src/authentication_service.rs b/bindings/matrix-sdk-ffi/src/authentication_service.rs index ae454ec78..2a115f5a7 100644 --- a/bindings/matrix-sdk-ffi/src/authentication_service.rs +++ b/bindings/matrix-sdk-ffi/src/authentication_service.rs @@ -30,12 +30,14 @@ impl From for AuthenticationError { } } +#[derive(uniffi::Object)] pub struct HomeserverLoginDetails { url: String, authentication_issuer: Option, supports_password_login: bool, } +#[uniffi::export] impl HomeserverLoginDetails { /// The URL of the currently configured homeserver. pub fn url(&self) -> String { @@ -54,6 +56,13 @@ impl HomeserverLoginDetails { } } +#[uniffi::export] +impl AuthenticationService { + pub fn homeserver_details(&self) -> Option> { + self.homeserver_details.read().unwrap().clone() + } +} + impl AuthenticationService { /// Creates a new service to authenticate a user with. pub fn new(base_path: String) -> Self { @@ -64,10 +73,6 @@ impl AuthenticationService { } } - pub fn homeserver_details(&self) -> Option> { - self.homeserver_details.read().unwrap().clone() - } - /// Updates the service to authenticate with the homeserver for the /// specified address. pub fn configure_homeserver(&self, server_name: String) -> Result<(), AuthenticationError> { diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index 01d0204f3..452b3491a 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -130,66 +130,6 @@ impl Client { .block_on(async move { self.client.whoami().await.map_err(|e| anyhow!(e.to_string())) }) } - pub fn start_sync(&self, timeline_limit: Option) { - let client = self.client.clone(); - let state = self.state.clone(); - let delegate = self.delegate.clone(); - let session_verification_controller = self.session_verification_controller.clone(); - let local_self = self.clone(); - RUNTIME.spawn(async move { - let mut filter = FilterDefinition::default(); - let mut room_filter = RoomFilter::default(); - let mut event_filter = RoomEventFilter::default(); - let mut timeline_filter = RoomEventFilter::default(); - - event_filter.lazy_load_options = - LazyLoadOptions::Enabled { include_redundant_members: false }; - room_filter.state = event_filter; - filter.room = room_filter; - - timeline_filter.limit = timeline_limit.map(|limit| limit.into()); - filter.room.timeline = timeline_filter; - - let filter_id = client.get_or_upload_filter("sync", filter).await.unwrap(); - - let sync_settings = SyncSettings::new().filter(Filter::FilterId(&filter_id)); - - client - .sync_with_result_callback(sync_settings, |result| async { - Ok(if let Ok(sync_response) = result { - if !state.read().unwrap().has_first_synced { - state.write().unwrap().has_first_synced = true; - } - - if state.read().unwrap().should_stop_syncing { - state.write().unwrap().is_syncing = false; - return Ok(LoopCtrl::Break); - } else if !state.read().unwrap().is_syncing { - state.write().unwrap().is_syncing = true; - } - - if let Some(delegate) = &*delegate.read().unwrap() { - delegate.did_receive_sync_update() - } - - if let Some(session_verification_controller) = - &*session_verification_controller.read().await - { - session_verification_controller - .process_to_device_messages(sync_response.to_device) - .await; - } - - LoopCtrl::Continue - } else { - local_self.process_sync_error(result.err().unwrap()) - }) - }) - .await - .unwrap(); - }); - } - pub fn restore_token(&self) -> anyhow::Result { RUNTIME.block_on(async move { let session = self.client.session().expect("Missing session"); @@ -376,6 +316,66 @@ impl Client { pub fn rooms(&self) -> Vec> { self.client.rooms().into_iter().map(|room| Arc::new(Room::new(room))).collect() } + + pub fn start_sync(&self, timeline_limit: Option) { + let client = self.client.clone(); + let state = self.state.clone(); + let delegate = self.delegate.clone(); + let session_verification_controller = self.session_verification_controller.clone(); + let local_self = self.clone(); + RUNTIME.spawn(async move { + let mut filter = FilterDefinition::default(); + let mut room_filter = RoomFilter::default(); + let mut event_filter = RoomEventFilter::default(); + let mut timeline_filter = RoomEventFilter::default(); + + event_filter.lazy_load_options = + LazyLoadOptions::Enabled { include_redundant_members: false }; + room_filter.state = event_filter; + filter.room = room_filter; + + timeline_filter.limit = timeline_limit.map(|limit| limit.into()); + filter.room.timeline = timeline_filter; + + let filter_id = client.get_or_upload_filter("sync", filter).await.unwrap(); + + let sync_settings = SyncSettings::new().filter(Filter::FilterId(&filter_id)); + + client + .sync_with_result_callback(sync_settings, |result| async { + Ok(if let Ok(sync_response) = result { + if !state.read().unwrap().has_first_synced { + state.write().unwrap().has_first_synced = true; + } + + if state.read().unwrap().should_stop_syncing { + state.write().unwrap().is_syncing = false; + return Ok(LoopCtrl::Break); + } else if !state.read().unwrap().is_syncing { + state.write().unwrap().is_syncing = true; + } + + if let Some(delegate) = &*delegate.read().unwrap() { + delegate.did_receive_sync_update() + } + + if let Some(session_verification_controller) = + &*session_verification_controller.read().await + { + session_verification_controller + .process_to_device_messages(sync_response.to_device) + .await; + } + + LoopCtrl::Continue + } else { + local_self.process_sync_error(result.err().unwrap()) + }) + }) + .await + .unwrap(); + }); + } } #[uniffi::export] diff --git a/bindings/matrix-sdk-ffi/src/lib.rs b/bindings/matrix-sdk-ffi/src/lib.rs index 9dc3e3bbf..ccee474c3 100644 --- a/bindings/matrix-sdk-ffi/src/lib.rs +++ b/bindings/matrix-sdk-ffi/src/lib.rs @@ -74,4 +74,16 @@ fn setup_tracing(configuration: String) { mod uniffi_types { pub use matrix_sdk::ruma::events::room::{message::RoomMessageEventContent, MediaSource}; + + pub use crate::{ + authentication_service::{AuthenticationService, HomeserverLoginDetails}, + client::Client, + messages::AnyMessage, + room::Room, + session_verification::SessionVerificationEmoji, + sliding_sync::{ + SlidingSync, SlidingSyncBuilder, SlidingSyncRoom, SlidingSyncView, StoppableSpawn, + UnreadNotificationsCount, + }, + }; } diff --git a/bindings/matrix-sdk-ffi/src/room.rs b/bindings/matrix-sdk-ffi/src/room.rs index 2dfd020b8..104b48b94 100644 --- a/bindings/matrix-sdk-ffi/src/room.rs +++ b/bindings/matrix-sdk-ffi/src/room.rs @@ -25,11 +25,8 @@ pub struct Room { room: MatrixRoom, } +#[uniffi::export] impl Room { - pub fn new(room: MatrixRoom) -> Self { - Room { room } - } - pub fn id(&self) -> String { self.room.room_id().to_string() } @@ -38,11 +35,6 @@ impl Room { self.room.name() } - pub fn display_name(&self) -> Result { - let r = self.room.clone(); - RUNTIME.block_on(async move { Ok(r.display_name().await?.to_string()) }) - } - pub fn topic(&self) -> Option { self.room.topic() } @@ -51,6 +43,37 @@ impl Room { self.room.avatar_url().map(|m| m.to_string()) } + pub fn is_direct(&self) -> bool { + self.room.is_direct() + } + + pub fn is_public(&self) -> bool { + self.room.is_public() + } + + pub fn is_encrypted(&self) -> bool { + self.room.is_encrypted() + } + + pub fn is_space(&self) -> bool { + self.room.is_space() + } + + pub fn is_tombstoned(&self) -> bool { + self.room.is_tombstoned() + } +} + +impl Room { + pub fn new(room: MatrixRoom) -> Self { + Room { room } + } + + pub fn display_name(&self) -> Result { + let r = self.room.clone(); + RUNTIME.block_on(async move { Ok(r.display_name().await?.to_string()) }) + } + pub fn member_avatar_url(&self, user_id: String) -> Result> { let room = self.room.clone(); let user_id = user_id; @@ -81,26 +104,6 @@ impl Room { } } - pub fn is_direct(&self) -> bool { - self.room.is_direct() - } - - pub fn is_public(&self) -> bool { - self.room.is_public() - } - - pub fn is_encrypted(&self) -> bool { - self.room.is_encrypted() - } - - pub fn is_space(&self) -> bool { - self.room.is_space() - } - - pub fn is_tombstoned(&self) -> bool { - self.room.is_tombstoned() - } - pub fn send(&self, msg: Arc, txn_id: Option) -> Result<()> { let room = match &self.room { MatrixRoom::Joined(j) => j.clone(), diff --git a/bindings/matrix-sdk-ffi/src/session_verification.rs b/bindings/matrix-sdk-ffi/src/session_verification.rs index 52434a5be..bc9b3d59e 100644 --- a/bindings/matrix-sdk-ffi/src/session_verification.rs +++ b/bindings/matrix-sdk-ffi/src/session_verification.rs @@ -18,6 +18,7 @@ pub struct SessionVerificationEmoji { description: String, } +#[uniffi::export] impl SessionVerificationEmoji { pub fn symbol(&self) -> String { self.symbol.clone() diff --git a/bindings/matrix-sdk-ffi/src/sliding_sync.rs b/bindings/matrix-sdk-ffi/src/sliding_sync.rs index 6e32d4db3..36bc48086 100644 --- a/bindings/matrix-sdk-ffi/src/sliding_sync.rs +++ b/bindings/matrix-sdk-ffi/src/sliding_sync.rs @@ -18,8 +18,8 @@ pub use matrix_sdk::{ }; use tokio::task::JoinHandle; -use super::{Client, RUNTIME}; -use crate::helpers::unwrap_or_clone_arc; +use super::{Client, Room, RUNTIME}; +use crate::{helpers::unwrap_or_clone_arc, messages::AnyMessage}; pub struct StoppableSpawn { handle: Arc>>>, @@ -33,7 +33,10 @@ impl StoppableSpawn { fn with_handle_ref(handle: Arc>>>) -> StoppableSpawn { StoppableSpawn { handle } } +} +#[uniffi::export] +impl StoppableSpawn { pub fn cancel(&self) { if let Some(handle) = self.handle.write().unwrap().take() { handle.abort(); @@ -44,11 +47,13 @@ impl StoppableSpawn { } } +#[derive(uniffi::Object)] pub struct UnreadNotificationsCount { highlight_count: u32, notification_count: u32, } +#[uniffi::export] impl UnreadNotificationsCount { pub fn highlight_count(&self) -> u32 { self.highlight_count @@ -81,6 +86,7 @@ pub struct SlidingSyncRoom { client: Client, } +#[uniffi::export] impl SlidingSyncRoom { pub fn name(&self) -> Option { self.inner.name().map(ToOwned::to_owned) @@ -110,7 +116,7 @@ impl SlidingSyncRoom { } #[allow(clippy::significant_drop_in_scrutinee)] - pub fn latest_room_message(&self) -> Option> { + pub fn latest_room_message(&self) -> Option> { let messages = self.inner.timeline(); // room is having the latest events at the end, let lock = messages.lock_ref(); @@ -122,8 +128,8 @@ impl SlidingSyncRoom { None } - pub fn full_room(&self) -> Option> { - self.client.get_room(self.inner.room_id()).map(|room| Arc::new(super::Room::new(room))) + pub fn full_room(&self) -> Option> { + self.client.get_room(self.inner.room_id()).map(|room| Arc::new(Room::new(room))) } } @@ -381,6 +387,13 @@ impl SlidingSyncView { }))) } + pub fn current_rooms_list(&self) -> Vec { + self.inner.rooms_list.lock_ref().as_slice().iter().map(|e| e.into()).collect() + } +} + +#[uniffi::export] +impl SlidingSyncView { /// Reset the ranges to a particular set /// /// Remember to cancel the existing stream and fetch a new one as this will @@ -404,10 +417,6 @@ impl SlidingSyncView { pub fn current_room_count(&self) -> Option { self.inner.rooms_count.get_cloned() } - - pub fn current_rooms_list(&self) -> Vec { - self.inner.rooms_list.lock_ref().as_slice().iter().map(|e| e.into()).collect() - } } pub trait SlidingSyncObserver: Sync + Send { @@ -481,7 +490,10 @@ impl SlidingSync { }) .collect()) } +} +#[uniffi::export] +impl SlidingSync { pub fn sync(&self) -> Arc { let inner = self.inner.clone(); let observer = self.observer.clone(); @@ -572,7 +584,10 @@ impl Client { Ok(Arc::new(SlidingSync::new(inner, self.clone()))) }) } +} +#[uniffi::export] +impl Client { pub fn sliding_sync(&self) -> Arc { RUNTIME.block_on(async move { let inner = self.client.sliding_sync().await;