From fa93daabd2cdcf62a05c8eefd7da9116809dd062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 22 Nov 2024 09:52:30 +0100 Subject: [PATCH] feat(ffi): Add `RoomInfo::join_rule` field to bindings Breaking-Change: Add `RoomInfo::join_rule` field, remove `RoomInfo::is_public` in the FFI crate, as they contain the same info. --- bindings/matrix-sdk-ffi/src/client.rs | 73 +++++++++++++++++++++--- bindings/matrix-sdk-ffi/src/room_info.rs | 12 +++- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index 47012ebaf..0a50f9716 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -55,7 +55,12 @@ use ruma::{ }, events::{ ignored_user_list::IgnoredUserListEventContent, - room::{join_rules::RoomJoinRulesEventContent, power_levels::RoomPowerLevelsEventContent}, + room::{ + join_rules::{ + AllowRule as RumaAllowRule, JoinRule as RumaJoinRule, RoomJoinRulesEventContent, + }, + power_levels::RoomPowerLevelsEventContent, + }, GlobalAccountDataEventType, }, push::{HttpPusherData as RumaHttpPusherData, PushFormat as RumaPushFormat}, @@ -1917,9 +1922,13 @@ pub enum AllowRule { /// Only a member of the `room_id` Room can join the one this rule is used /// in. RoomMembership { room_id: String }, + + /// A custom allow rule implementation, containing its JSON representation + /// as a `String`. + Custom { json: String }, } -impl TryFrom for ruma::events::room::join_rules::JoinRule { +impl TryFrom for RumaJoinRule { type Error = ClientError; fn try_from(value: JoinRule) -> Result { @@ -1929,11 +1938,11 @@ impl TryFrom for ruma::events::room::join_rules::JoinRule { JoinRule::Knock => Ok(Self::Knock), JoinRule::Private => Ok(Self::Private), JoinRule::Restricted { rules } => { - let rules = allow_rules_from(rules)?; + let rules = ruma_allow_rules_from_ffi(rules)?; Ok(Self::Restricted(ruma::events::room::join_rules::Restricted::new(rules))) } JoinRule::KnockRestricted { rules } => { - let rules = allow_rules_from(rules)?; + let rules = ruma_allow_rules_from_ffi(rules)?; Ok(Self::KnockRestricted(ruma::events::room::join_rules::Restricted::new(rules))) } JoinRule::Custom { repr } => Ok(serde_json::from_str(&repr)?), @@ -1941,12 +1950,10 @@ impl TryFrom for ruma::events::room::join_rules::JoinRule { } } -fn allow_rules_from( - value: Vec, -) -> Result, ClientError> { +fn ruma_allow_rules_from_ffi(value: Vec) -> Result, ClientError> { let mut ret = Vec::with_capacity(value.len()); for rule in value { - let rule: Result = rule.try_into(); + let rule: Result = rule.try_into(); match rule { Ok(rule) => ret.push(rule), Err(error) => return Err(error), @@ -1955,7 +1962,7 @@ fn allow_rules_from( Ok(ret) } -impl TryFrom for ruma::events::room::join_rules::AllowRule { +impl TryFrom for RumaAllowRule { type Error = ClientError; fn try_from(value: AllowRule) -> Result { @@ -1966,6 +1973,54 @@ impl TryFrom for ruma::events::room::join_rules::AllowRule { room_id, ))) } + AllowRule::Custom { json } => Ok(Self::_Custom(Box::new(serde_json::from_str(&json)?))), + } + } +} + +impl TryFrom for JoinRule { + type Error = String; + fn try_from(value: RumaJoinRule) -> Result { + match value { + RumaJoinRule::Knock => Ok(JoinRule::Knock), + RumaJoinRule::Public => Ok(JoinRule::Public), + RumaJoinRule::Private => Ok(JoinRule::Private), + RumaJoinRule::KnockRestricted(restricted) => { + let rules = restricted.allow.into_iter().map(TryInto::try_into).collect::, + Self::Error, + >>( + )?; + Ok(JoinRule::KnockRestricted { rules }) + } + RumaJoinRule::Restricted(restricted) => { + let rules = restricted.allow.into_iter().map(TryInto::try_into).collect::, + Self::Error, + >>( + )?; + Ok(JoinRule::Restricted { rules }) + } + RumaJoinRule::Invite => Ok(JoinRule::Invite), + RumaJoinRule::_Custom(_) => Ok(JoinRule::Custom { repr: value.as_str().to_owned() }), + _ => Err(format!("Unknown JoinRule: {:?}", value)), + } + } +} + +impl TryFrom for AllowRule { + type Error = String; + fn try_from(value: RumaAllowRule) -> Result { + match value { + RumaAllowRule::RoomMembership(membership) => { + Ok(AllowRule::RoomMembership { room_id: membership.room_id.to_string() }) + } + RumaAllowRule::_Custom(repr) => { + let json = serde_json::to_string(&repr) + .map_err(|e| format!("Couldn't serialize custom AllowRule: {e:?}"))?; + Ok(Self::Custom { json }) + } + _ => Err(format!("Invalid AllowRule: {:?}", value)), } } } diff --git a/bindings/matrix-sdk-ffi/src/room_info.rs b/bindings/matrix-sdk-ffi/src/room_info.rs index 96de331fd..1b0f27e71 100644 --- a/bindings/matrix-sdk-ffi/src/room_info.rs +++ b/bindings/matrix-sdk-ffi/src/room_info.rs @@ -1,8 +1,10 @@ use std::collections::HashMap; use matrix_sdk::RoomState; +use tracing::warn; use crate::{ + client::JoinRule, notification_settings::RoomNotificationMode, room::{Membership, RoomHero}, room_member::RoomMember, @@ -54,8 +56,10 @@ pub struct RoomInfo { /// Events causing mentions/highlights for the user, according to their /// notification settings. num_unread_mentions: u64, - /// The currently pinned event ids + /// The currently pinned event ids. pinned_event_ids: Vec, + /// The join rule for this room, if known. + join_rule: Option, } impl RoomInfo { @@ -70,6 +74,11 @@ impl RoomInfo { let pinned_event_ids = room.pinned_event_ids().unwrap_or_default().iter().map(|id| id.to_string()).collect(); + let join_rule = room.join_rule().try_into(); + if let Err(e) = &join_rule { + warn!("Failed to parse join rule: {:?}", e); + } + Ok(Self { id: room.room_id().to_string(), creator: room.creator().as_ref().map(ToString::to_string), @@ -118,6 +127,7 @@ impl RoomInfo { num_unread_notifications: room.num_unread_notifications(), num_unread_mentions: room.num_unread_mentions(), pinned_event_ids, + join_rule: join_rule.ok(), }) } }