refactor(bindings): Use uniffi proc-macros more in sdk-ffi

This commit is contained in:
Jonas Platte
2022-10-20 13:24:20 +02:00
committed by Jonas Platte
parent 99e621a82b
commit 4c4b1f3abc
6 changed files with 101 additions and 239 deletions

View File

@@ -30,7 +30,6 @@ dictionary UpdateSummary {
sequence<string> 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<string> sort);
[Self=ByArc]
SlidingSyncViewBuilder add_range(u32 from, u32 to);
[Self=ByArc]
SlidingSyncViewBuilder reset_ranges();
[Self=ByArc]
SlidingSyncViewBuilder required_state(sequence<RequiredState> 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<RoomListEntry> 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<TimelineItem>? 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<Reaction> 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();

View File

@@ -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,
},
};
}

View File

@@ -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<dyn TimelineListener>) {
let timeline_signal = self
.timeline

View File

@@ -44,6 +44,13 @@ pub struct SessionVerificationController {
sas_verification: Arc<RwLock<Option<SasVerification>>>,
}
#[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];

View File

@@ -154,6 +154,7 @@ pub struct UpdateSummary {
pub rooms: Vec<String>,
}
#[derive(uniffi::Record)]
pub struct RequiredState {
pub key: String,
pub value: String,
@@ -223,7 +224,7 @@ impl From<VecDiff<MatrixRoomEntry>> 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<Self>, ranges: Vec<(u32, u32)>) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.inner = builder.inner.ranges(ranges);
Arc::new(builder)
}
pub fn build(self: Arc<Self>) -> anyhow::Result<Arc<SlidingSyncView>> {
let builder = unwrap_or_clone_arc(self);
Ok(Arc::new(builder.inner.build()?.into()))
}
}
#[uniffi::export]
impl SlidingSyncViewBuilder {
pub fn sort(self: Arc<Self>, sort: Vec<String>) -> Arc<Self> {
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<Self>, ranges: Vec<(u32, u32)>) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.inner = builder.inner.ranges(ranges);
Arc::new(builder)
}
pub fn add_range(self: Arc<Self>, from: u32, to: u32) -> Arc<Self> {
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<Self>) -> anyhow::Result<Arc<SlidingSyncView>> {
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<RoomListEntry> {
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<Arc<SlidingSyncView>> {
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<Option<Arc<SlidingSyncRoom>>> {
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<Arc<SlidingSyncView>> {
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<StoppableSpawn> {
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<Self>) -> anyhow::Result<Arc<SlidingSync>> {
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<Self>) -> Arc<Self> {
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<Self>) -> anyhow::Result<Arc<SlidingSync>> {
let builder = unwrap_or_clone_arc(self);
Ok(Arc::new(SlidingSync::new(builder.inner.build()?, builder.client)))
}
}
impl Client {

View File

@@ -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<Self>) -> Option<Arc<TimelineItem>> {
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<MoveData> {
match &self.0 {
VecDiff::Move { old_index, new_index } => Some(MoveData {
@@ -90,17 +100,15 @@ impl TimelineDiff {
_ => None,
}
}
pub fn push(self: Arc<Self>) -> Option<Arc<TimelineItem>> {
unwrap_or_clone_arc_into_variant!(self, .0, VecDiff::Push { value } => value)
}
}
#[derive(uniffi::Record)]
pub struct InsertAtData {
pub index: u32,
pub item: Arc<TimelineItem>,
}
#[derive(uniffi::Record)]
pub struct UpdateAtData {
pub index: u32,
pub item: Arc<TimelineItem>,
@@ -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<Reaction> {
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<String> {
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<Reaction> {
self.0
.reactions()
.iter()
.map(|(k, v)| Reaction { key: k.to_owned(), count: v.count.into() })
.collect()
}
pub fn raw(&self) -> Option<String> {
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<MessageType> {
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<FormattedBody>,
}
#[derive(Clone)]
#[derive(Clone, uniffi::Record)]
pub struct ImageMessageContent {
pub body: String,
pub source: Arc<MediaSource>,
pub info: Option<ImageInfo>,
}
#[derive(Clone)]
#[derive(Clone, uniffi::Record)]
pub struct ImageInfo {
pub height: Option<u64>,
pub width: Option<u64>,
@@ -304,7 +309,7 @@ pub struct ImageInfo {
pub blurhash: Option<String>,
}
#[derive(Clone)]
#[derive(Clone, uniffi::Record)]
pub struct ThumbnailInfo {
pub height: Option<u64>,
pub width: Option<u64>,
@@ -312,19 +317,19 @@ pub struct ThumbnailInfo {
pub size: Option<u64>,
}
#[derive(Clone)]
#[derive(Clone, uniffi::Record)]
pub struct NoticeMessageContent {
pub body: String,
pub formatted: Option<FormattedBody>,
}
#[derive(Clone)]
#[derive(Clone, uniffi::Record)]
pub struct TextMessageContent {
pub body: String,
pub formatted: Option<FormattedBody>,
}
#[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]