matrix_sdk_ffi/
room_member.rs1use matrix_sdk::room::{RoomMember as SdkRoomMember, RoomMemberRole};
2use ruma::{events::room::power_levels::UserPowerLevel, UserId};
3
4use crate::error::{ClientError, NotYetImplemented};
5
6#[derive(Clone, uniffi::Enum)]
7pub enum MembershipState {
8 Ban,
10
11 Invite,
13
14 Join,
16
17 Knock,
19
20 Leave,
22
23 Custom { value: String },
25}
26
27impl TryFrom<matrix_sdk::ruma::events::room::member::MembershipState> for MembershipState {
28 type Error = NotYetImplemented;
29
30 fn try_from(
31 m: matrix_sdk::ruma::events::room::member::MembershipState,
32 ) -> Result<Self, Self::Error> {
33 match m {
34 matrix_sdk::ruma::events::room::member::MembershipState::Ban => {
35 Ok(MembershipState::Ban)
36 }
37 matrix_sdk::ruma::events::room::member::MembershipState::Invite => {
38 Ok(MembershipState::Invite)
39 }
40 matrix_sdk::ruma::events::room::member::MembershipState::Join => {
41 Ok(MembershipState::Join)
42 }
43 matrix_sdk::ruma::events::room::member::MembershipState::Knock => {
44 Ok(MembershipState::Knock)
45 }
46 matrix_sdk::ruma::events::room::member::MembershipState::Leave => {
47 Ok(MembershipState::Leave)
48 }
49 matrix_sdk::ruma::events::room::member::MembershipState::_Custom(_) => {
50 Ok(MembershipState::Custom { value: m.to_string() })
51 }
52 _ => {
53 tracing::warn!("Other membership state change not yet implemented");
54 Err(NotYetImplemented)
55 }
56 }
57 }
58}
59
60#[matrix_sdk_ffi_macros::export]
65pub fn suggested_role_for_power_level(
66 power_level: PowerLevel,
67) -> Result<RoomMemberRole, ClientError> {
68 Ok(RoomMemberRole::suggested_role_for_power_level(power_level.try_into()?))
70}
71
72#[matrix_sdk_ffi_macros::export]
76pub fn suggested_power_level_for_role(role: RoomMemberRole) -> Result<PowerLevel, ClientError> {
77 Ok(role.suggested_power_level().try_into()?)
79}
80
81#[matrix_sdk_ffi_macros::export]
83pub fn matrix_to_user_permalink(user_id: String) -> Result<String, ClientError> {
84 let user_id = UserId::parse(user_id)?;
85 Ok(user_id.matrix_to_uri().to_string())
86}
87
88#[derive(Clone, uniffi::Record)]
89pub struct RoomMember {
90 pub user_id: String,
91 pub display_name: Option<String>,
92 pub avatar_url: Option<String>,
93 pub membership: MembershipState,
94 pub is_name_ambiguous: bool,
95 pub power_level: PowerLevel,
96 pub is_ignored: bool,
97 pub suggested_role_for_power_level: RoomMemberRole,
98 pub membership_change_reason: Option<String>,
99}
100
101impl TryFrom<SdkRoomMember> for RoomMember {
102 type Error = NotYetImplemented;
103
104 fn try_from(m: SdkRoomMember) -> Result<Self, Self::Error> {
105 Ok(RoomMember {
106 user_id: m.user_id().to_string(),
107 display_name: m.display_name().map(|s| s.to_owned()),
108 avatar_url: m.avatar_url().map(|a| a.to_string()),
109 membership: m.membership().clone().try_into()?,
110 is_name_ambiguous: m.name_ambiguous(),
111 power_level: m.power_level().try_into()?,
112 is_ignored: m.is_ignored(),
113 suggested_role_for_power_level: m.suggested_role_for_power_level(),
114 membership_change_reason: m.event().reason().map(|s| s.to_owned()),
115 })
116 }
117}
118
119#[derive(Clone, uniffi::Record)]
122pub struct RoomMemberWithSenderInfo {
123 room_member: RoomMember,
125 sender_info: Option<RoomMember>,
128}
129
130impl TryFrom<matrix_sdk::room::RoomMemberWithSenderInfo> for RoomMemberWithSenderInfo {
131 type Error = ClientError;
132
133 fn try_from(value: matrix_sdk::room::RoomMemberWithSenderInfo) -> Result<Self, Self::Error> {
134 Ok(Self {
135 room_member: value.room_member.try_into()?,
136 sender_info: value.sender_info.map(|member| member.try_into()).transpose()?,
137 })
138 }
139}
140
141#[derive(Clone, uniffi::Enum)]
142pub enum PowerLevel {
143 Infinite,
147
148 Value { value: i64 },
150}
151
152impl TryFrom<UserPowerLevel> for PowerLevel {
153 type Error = NotYetImplemented;
154
155 fn try_from(value: UserPowerLevel) -> Result<Self, Self::Error> {
156 match value {
157 UserPowerLevel::Infinite => Ok(Self::Infinite),
158 UserPowerLevel::Int(value) => Ok(Self::Value { value: value.into() }),
159 _ => Err(NotYetImplemented),
160 }
161 }
162}
163
164impl TryFrom<PowerLevel> for UserPowerLevel {
165 type Error = ClientError;
166
167 fn try_from(value: PowerLevel) -> Result<Self, Self::Error> {
168 Ok(match value {
169 PowerLevel::Infinite => Self::Infinite,
170 PowerLevel::Value { value } => {
171 Self::Int(value.try_into().map_err(|err| ClientError::Generic {
172 msg: "Power level is out of range".to_owned(),
173 details: Some(format!("{err:?}")),
174 })?)
175 }
176 })
177 }
178}