From 4c4b1f3abc73e9241ebadf2f24cf48b79a3e0ed4 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 20 Oct 2022 13:24:20 +0200 Subject: [PATCH] refactor(bindings): Use uniffi proc-macros more in sdk-ffi --- bindings/matrix-sdk-ffi/src/api.udl | 161 ------------------ bindings/matrix-sdk-ffi/src/lib.rs | 13 +- bindings/matrix-sdk-ffi/src/room.rs | 17 +- .../src/session_verification.rs | 11 +- bindings/matrix-sdk-ffi/src/sliding_sync.rs | 67 +++++--- bindings/matrix-sdk-ffi/src/timeline.rs | 71 ++++---- 6 files changed, 101 insertions(+), 239 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/api.udl b/bindings/matrix-sdk-ffi/src/api.udl index 61b7da5ee..b2bdff5bd 100644 --- a/bindings/matrix-sdk-ffi/src/api.udl +++ b/bindings/matrix-sdk-ffi/src/api.udl @@ -30,7 +30,6 @@ dictionary UpdateSummary { sequence rooms; }; - callback interface SlidingSyncObserver { void did_receive_sync_update(UpdateSummary summary); }; @@ -101,30 +100,9 @@ callback interface SlidingSyncViewRoomItemsObserver { interface SlidingSyncViewBuilder { constructor(); - [Self=ByArc] - SlidingSyncViewBuilder timeline_limit(u32 limit); - [Self=ByArc] SlidingSyncViewBuilder sync_mode(SlidingSyncMode mode); - [Self=ByArc] - SlidingSyncViewBuilder batch_size(u32 size); - - [Self=ByArc] - SlidingSyncViewBuilder name(string name); - - [Self=ByArc] - SlidingSyncViewBuilder sort(sequence sort); - - [Self=ByArc] - SlidingSyncViewBuilder add_range(u32 from, u32 to); - - [Self=ByArc] - SlidingSyncViewBuilder reset_ranges(); - - [Self=ByArc] - SlidingSyncViewBuilder required_state(sequence required_state); - [Throws=ClientError, Self=ByArc] SlidingSyncView build(); }; @@ -134,8 +112,6 @@ interface SlidingSyncView { StoppableSpawn observe_rooms_count(SlidingSyncViewRoomsCountObserver observer); StoppableSpawn observe_state(SlidingSyncViewStateObserver observer); StoppableSpawn observe_room_items(SlidingSyncViewRoomItemsObserver observer); - - sequence current_rooms_list(); }; interface SlidingSyncRoom {}; @@ -148,7 +124,6 @@ interface SlidingSync { [Throws=ClientError] void unsubscribe(string room_id); - SlidingSyncView? get_view(string name); [Throws=ClientError] SlidingSyncRoom? get_room(string room_id); [Throws=ClientError] @@ -166,18 +141,6 @@ interface SlidingSyncBuilder { [Throws=ClientError, Self=ByArc] SlidingSyncBuilder homeserver(string url); - [Self=ByArc] - SlidingSyncBuilder add_fullsync_view(); - - [Self=ByArc] - SlidingSyncBuilder no_views(); - - [Self=ByArc] - SlidingSyncBuilder add_view(SlidingSyncView view); - - [Self=ByArc] - SlidingSyncBuilder with_common_extensions(); - [Throws=ClientError, Self=ByArc] SlidingSync build(); }; @@ -228,15 +191,7 @@ interface Client { void logout(); }; -enum Membership { - "Invited", - "Joined", - "Left", -}; - interface Room { - Membership membership(); - [Throws=ClientError] string display_name(); @@ -269,39 +224,7 @@ callback interface TimelineListener { }; interface TimelineDiff { - TimelineChange change(); - - [Self=ByArc] - sequence? replace(); - [Self=ByArc] - InsertAtData? insert_at(); - [Self=ByArc] - UpdateAtData? update_at(); - u32? remove_at(); MoveData? move(); - [Self=ByArc] - TimelineItem? push(); -}; - -enum TimelineChange { - "Replace", - "InsertAt", - "UpdateAt", - "RemoveAt", - "Move", - "Push", - "Pop", - "Clear", -}; - -dictionary InsertAtData { - u32 index; - TimelineItem item; -}; - -dictionary UpdateAtData { - u32 index; - TimelineItem item; }; dictionary MoveData { @@ -309,88 +232,6 @@ dictionary MoveData { u32 new_index; }; -interface TimelineItem {}; - -interface EventTimelineItem { - TimelineKey key(); - sequence reactions(); -}; - -[Enum] -interface TimelineKey { - TransactionId(string txn_id); - EventId(string event_id); -}; - -// Other methods defined via proc-macro -interface Message { - MessageType? msgtype(); -}; - -[Enum] -interface MessageType { - Emote(EmoteMessageContent content); - Image(ImageMessageContent content); - Notice(NoticeMessageContent content); - Text(TextMessageContent content); -}; - -dictionary EmoteMessageContent { - string body; - FormattedBody? formatted; -}; - -dictionary ImageMessageContent { - string body; - MediaSource source; - ImageInfo? info; -}; - -dictionary ImageInfo { - u64? height; - u64? width; - string? mimetype; - u64? size; - ThumbnailInfo? thumbnail_info; - MediaSource? thumbnail_source; - string? blurhash; -}; - -dictionary ThumbnailInfo { - u64? height; - u64? width; - string? mimetype; - u64? size; -}; - -dictionary NoticeMessageContent { - string body; - FormattedBody? formatted; -}; - -dictionary TextMessageContent { - string body; - FormattedBody? formatted; -}; - -dictionary FormattedBody { - MessageFormat format; - string body; -}; - -enum MessageFormat { - "Html", - "Unknown", -}; - -dictionary Reaction { - string key; - u64 count; - // senders to come -}; - -interface VirtualTimelineItem {}; - dictionary PaginationOutcome { // Whether there's more messages to be paginated. boolean more_messages; @@ -434,8 +275,6 @@ callback interface SessionVerificationControllerDelegate { interface SessionVerificationController { void set_delegate(SessionVerificationControllerDelegate? delegate); - boolean is_verified(); - [Throws=ClientError] void request_verification(); diff --git a/bindings/matrix-sdk-ffi/src/lib.rs b/bindings/matrix-sdk-ffi/src/lib.rs index fbc927c2c..8c1b48000 100644 --- a/bindings/matrix-sdk-ffi/src/lib.rs +++ b/bindings/matrix-sdk-ffi/src/lib.rs @@ -99,14 +99,17 @@ mod uniffi_types { authentication_service::{AuthenticationService, HomeserverLoginDetails}, client::Client, client_builder::ClientBuilder, - room::Room, - session_verification::SessionVerificationEmoji, + room::{Membership, Room}, + session_verification::{SessionVerificationController, SessionVerificationEmoji}, sliding_sync::{ - SlidingSync, SlidingSyncBuilder, SlidingSyncRoom, SlidingSyncView, StoppableSpawn, - UnreadNotificationsCount, + RequiredState, RoomListEntry, SlidingSync, SlidingSyncBuilder, SlidingSyncRoom, + SlidingSyncView, SlidingSyncViewBuilder, StoppableSpawn, UnreadNotificationsCount, }, timeline::{ - EventTimelineItem, Message, TimelineItem, TimelineItemContent, VirtualTimelineItem, + EmoteMessageContent, EventTimelineItem, FormattedBody, ImageInfo, ImageMessageContent, + InsertAtData, Message, MessageFormat, MessageType, NoticeMessageContent, Reaction, + TextMessageContent, ThumbnailInfo, TimelineChange, TimelineDiff, TimelineItem, + TimelineItemContent, TimelineKey, UpdateAtData, VirtualTimelineItem, }, }; } diff --git a/bindings/matrix-sdk-ffi/src/room.rs b/bindings/matrix-sdk-ffi/src/room.rs index ea77f0177..f39991bd2 100644 --- a/bindings/matrix-sdk-ffi/src/room.rs +++ b/bindings/matrix-sdk-ffi/src/room.rs @@ -20,6 +20,7 @@ use tracing::error; use super::RUNTIME; use crate::{TimelineDiff, TimelineListener}; +#[derive(uniffi::Enum)] pub enum Membership { Invited, Joined, @@ -69,6 +70,14 @@ impl Room { self.room.is_tombstoned() } + pub fn membership(&self) -> Membership { + match &self.room { + SdkRoom::Invited(_) => Membership::Invited, + SdkRoom::Joined(_) => Membership::Joined, + SdkRoom::Left(_) => Membership::Left, + } + } + /// Removes the timeline. /// /// Timeline items cached in memory as well as timeline listeners are @@ -110,14 +119,6 @@ impl Room { }) } - pub fn membership(&self) -> Membership { - match &self.room { - SdkRoom::Invited(_) => Membership::Invited, - SdkRoom::Joined(_) => Membership::Joined, - SdkRoom::Left(_) => Membership::Left, - } - } - pub fn add_timeline_listener(&self, listener: Box) { let timeline_signal = self .timeline diff --git a/bindings/matrix-sdk-ffi/src/session_verification.rs b/bindings/matrix-sdk-ffi/src/session_verification.rs index 0dde10eea..d2d175bc8 100644 --- a/bindings/matrix-sdk-ffi/src/session_verification.rs +++ b/bindings/matrix-sdk-ffi/src/session_verification.rs @@ -44,6 +44,13 @@ pub struct SessionVerificationController { sas_verification: Arc>>, } +#[uniffi::export] +impl SessionVerificationController { + pub fn is_verified(&self) -> bool { + self.user_identity.is_verified() + } +} + impl SessionVerificationController { pub fn new(user_identity: UserIdentity) -> Self { SessionVerificationController { @@ -58,10 +65,6 @@ impl SessionVerificationController { *self.delegate.write().unwrap() = delegate; } - pub fn is_verified(&self) -> bool { - self.user_identity.is_verified() - } - pub fn request_verification(&self) -> anyhow::Result<()> { RUNTIME.block_on(async move { let methods = vec![VerificationMethod::SasV1]; diff --git a/bindings/matrix-sdk-ffi/src/sliding_sync.rs b/bindings/matrix-sdk-ffi/src/sliding_sync.rs index 41ceb3f52..ec256f87d 100644 --- a/bindings/matrix-sdk-ffi/src/sliding_sync.rs +++ b/bindings/matrix-sdk-ffi/src/sliding_sync.rs @@ -154,6 +154,7 @@ pub struct UpdateSummary { pub rooms: Vec, } +#[derive(uniffi::Record)] pub struct RequiredState { pub key: String, pub value: String, @@ -223,7 +224,7 @@ impl From> for SlidingSyncViewRoomsListDiff { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, uniffi::Enum)] pub enum RoomListEntry { Empty, Invalidated { room_id: String }, @@ -241,6 +242,7 @@ impl From<&MatrixRoomEntry> for RoomListEntry { } } } + pub trait SlidingSyncViewRoomItemsObserver: Sync + Send { fn did_receive_update(&self); } @@ -272,6 +274,20 @@ impl SlidingSyncViewBuilder { Arc::new(builder) } + pub fn ranges(self: Arc, ranges: Vec<(u32, u32)>) -> Arc { + let mut builder = unwrap_or_clone_arc(self); + builder.inner = builder.inner.ranges(ranges); + Arc::new(builder) + } + + pub fn build(self: Arc) -> anyhow::Result> { + let builder = unwrap_or_clone_arc(self); + Ok(Arc::new(builder.inner.build()?.into())) + } +} + +#[uniffi::export] +impl SlidingSyncViewBuilder { pub fn sort(self: Arc, sort: Vec) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.inner = builder.inner.sort(sort); @@ -310,12 +326,6 @@ impl SlidingSyncViewBuilder { Arc::new(builder) } - pub fn ranges(self: Arc, ranges: Vec<(u32, u32)>) -> Arc { - let mut builder = unwrap_or_clone_arc(self); - builder.inner = builder.inner.ranges(ranges); - Arc::new(builder) - } - pub fn add_range(self: Arc, from: u32, to: u32) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.inner = builder.inner.add_range(from, to); @@ -327,11 +337,6 @@ impl SlidingSyncViewBuilder { builder.inner = builder.inner.reset_ranges(); Arc::new(builder) } - - pub fn build(self: Arc) -> anyhow::Result> { - let builder = unwrap_or_clone_arc(self); - Ok(Arc::new(builder.inner.build()?.into())) - } } #[derive(Clone)] @@ -401,7 +406,10 @@ impl SlidingSyncView { } }))) } +} +#[uniffi::export] +impl SlidingSyncView { pub fn current_rooms_list(&self) -> Vec { self.inner.rooms_list.lock_ref().as_slice().iter().map(|e| e.into()).collect() } @@ -470,17 +478,6 @@ impl SlidingSync { Ok(()) } - #[allow(clippy::significant_drop_in_scrutinee)] - pub fn get_view(&self, name: String) -> Option> { - let views = self.inner.views.lock_ref(); - for s in views.iter() { - if s.name == name { - return Some(Arc::new(SlidingSyncView { inner: s.clone() })); - } - } - None - } - pub fn get_room(&self, room_id: String) -> anyhow::Result>> { Ok(self .inner @@ -509,6 +506,17 @@ impl SlidingSync { #[uniffi::export] impl SlidingSync { + #[allow(clippy::significant_drop_in_scrutinee)] + pub fn get_view(&self, name: String) -> Option> { + let views = self.inner.views.lock_ref(); + for s in views.iter() { + if s.name == name { + return Some(Arc::new(SlidingSyncView { inner: s.clone() })); + } + } + None + } + pub fn sync(&self) -> Arc { let inner = self.inner.clone(); let observer = self.observer.clone(); @@ -569,6 +577,14 @@ impl SlidingSyncBuilder { Ok(Arc::new(builder)) } + pub fn build(self: Arc) -> anyhow::Result> { + let builder = unwrap_or_clone_arc(self); + Ok(Arc::new(SlidingSync::new(builder.inner.build()?, builder.client))) + } +} + +#[uniffi::export] +impl SlidingSyncBuilder { pub fn add_fullsync_view(self: Arc) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.inner = builder.inner.add_fullsync_view(); @@ -593,11 +609,6 @@ impl SlidingSyncBuilder { builder.inner = builder.inner.with_common_extensions(); Arc::new(builder) } - - pub fn build(self: Arc) -> anyhow::Result> { - let builder = unwrap_or_clone_arc(self); - Ok(Arc::new(SlidingSync::new(builder.inner.build()?, builder.client))) - } } impl Client { diff --git a/bindings/matrix-sdk-ffi/src/timeline.rs b/bindings/matrix-sdk-ffi/src/timeline.rs index fe38333b9..951a08416 100644 --- a/bindings/matrix-sdk-ffi/src/timeline.rs +++ b/bindings/matrix-sdk-ffi/src/timeline.rs @@ -44,7 +44,10 @@ impl TimelineDiff { VecDiff::Clear {} => VecDiff::Clear {}, }) } +} +#[uniffi::export] +impl TimelineDiff { pub fn change(&self) -> TimelineChange { match &self.0 { VecDiff::Replace { .. } => TimelineChange::Replace, @@ -81,6 +84,13 @@ impl TimelineDiff { } } + pub fn push(self: Arc) -> Option> { + unwrap_or_clone_arc_into_variant!(self, .0, VecDiff::Push { value } => value) + } +} + +// UniFFI currently chokes on the r# +impl TimelineDiff { pub fn r#move(&self) -> Option { match &self.0 { VecDiff::Move { old_index, new_index } => Some(MoveData { @@ -90,17 +100,15 @@ impl TimelineDiff { _ => None, } } - - pub fn push(self: Arc) -> Option> { - unwrap_or_clone_arc_into_variant!(self, .0, VecDiff::Push { value } => value) - } } +#[derive(uniffi::Record)] pub struct InsertAtData { pub index: u32, pub item: Arc, } +#[derive(uniffi::Record)] pub struct UpdateAtData { pub index: u32, pub item: Arc, @@ -111,7 +119,7 @@ pub struct MoveData { pub new_index: u32, } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, uniffi::Enum)] pub enum TimelineChange { Replace, InsertAt, @@ -124,7 +132,7 @@ pub enum TimelineChange { } #[repr(transparent)] -#[derive(Clone)] +#[derive(Clone, uniffi::Object)] pub struct TimelineItem(matrix_sdk::room::timeline::TimelineItem); impl TimelineItem { @@ -156,24 +164,15 @@ impl TimelineItem { } } +#[derive(uniffi::Object)] pub struct EventTimelineItem(pub(crate) matrix_sdk::room::timeline::EventTimelineItem); +#[uniffi::export] impl EventTimelineItem { pub fn key(&self) -> TimelineKey { self.0.key().into() } - pub fn reactions(&self) -> Vec { - self.0 - .reactions() - .iter() - .map(|(k, v)| Reaction { key: k.to_owned(), count: v.count.into() }) - .collect() - } -} - -#[uniffi::export] -impl EventTimelineItem { pub fn event_id(&self) -> Option { self.0.event_id().map(ToString::to_string) } @@ -194,6 +193,14 @@ impl EventTimelineItem { self.0.origin_server_ts().map(|ts| ts.0.into()) } + pub fn reactions(&self) -> Vec { + self.0 + .reactions() + .iter() + .map(|(k, v)| Reaction { key: k.to_owned(), count: v.count.into() }) + .collect() + } + pub fn raw(&self) -> Option { self.0.raw().map(|r| r.json().get().to_owned()) } @@ -219,9 +226,10 @@ impl TimelineItemContent { } } -#[derive(Clone)] +#[derive(Clone, uniffi::Object)] pub struct Message(matrix_sdk::room::timeline::Message); +#[uniffi::export] impl Message { pub fn msgtype(&self) -> Option { use matrix_sdk::ruma::events::room::message::MessageType as MTy; @@ -254,10 +262,7 @@ impl Message { _ => None, } } -} -#[uniffi::export] -impl Message { pub fn body(&self) -> String { self.0.msgtype().body().to_owned() } @@ -272,7 +277,7 @@ impl Message { } } -#[derive(Clone)] +#[derive(Clone, uniffi::Enum)] pub enum MessageType { Emote { content: EmoteMessageContent }, Image { content: ImageMessageContent }, @@ -280,20 +285,20 @@ pub enum MessageType { Text { content: TextMessageContent }, } -#[derive(Clone)] +#[derive(Clone, uniffi::Record)] pub struct EmoteMessageContent { pub body: String, pub formatted: Option, } -#[derive(Clone)] +#[derive(Clone, uniffi::Record)] pub struct ImageMessageContent { pub body: String, pub source: Arc, pub info: Option, } -#[derive(Clone)] +#[derive(Clone, uniffi::Record)] pub struct ImageInfo { pub height: Option, pub width: Option, @@ -304,7 +309,7 @@ pub struct ImageInfo { pub blurhash: Option, } -#[derive(Clone)] +#[derive(Clone, uniffi::Record)] pub struct ThumbnailInfo { pub height: Option, pub width: Option, @@ -312,19 +317,19 @@ pub struct ThumbnailInfo { pub size: Option, } -#[derive(Clone)] +#[derive(Clone, uniffi::Record)] pub struct NoticeMessageContent { pub body: String, pub formatted: Option, } -#[derive(Clone)] +#[derive(Clone, uniffi::Record)] pub struct TextMessageContent { pub body: String, pub formatted: Option, } -#[derive(Clone)] +#[derive(Clone, uniffi::Record)] pub struct FormattedBody { pub format: MessageFormat, pub body: String, @@ -342,7 +347,7 @@ impl From<&matrix_sdk::ruma::events::room::message::FormattedBody> for Formatted } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, uniffi::Enum)] pub enum MessageFormat { Html, Unknown, @@ -369,7 +374,7 @@ impl From<&matrix_sdk::ruma::events::room::ImageInfo> for ImageInfo { } } -#[derive(Clone)] +#[derive(Clone, uniffi::Record)] pub struct Reaction { pub key: String, pub count: u64, @@ -382,7 +387,7 @@ pub struct ReactionDetails { pub sender: String, } -#[derive(Clone)] +#[derive(Clone, uniffi::Enum)] pub enum TimelineKey { TransactionId { txn_id: String }, EventId { event_id: String }, @@ -399,7 +404,7 @@ impl From<&matrix_sdk::room::timeline::TimelineKey> for TimelineKey { } } -#[derive(Clone)] +#[derive(Clone, uniffi::Object)] pub struct VirtualTimelineItem(matrix_sdk::room::timeline::VirtualTimelineItem); #[extension_trait]