events: Move membership change logic into its own module
This commit is contained in:
parent
106441bdef
commit
e136f486db
@ -15,9 +15,13 @@ use crate::{
|
||||
},
|
||||
serde::StringEnum,
|
||||
MxcUri, OwnedServerName, OwnedServerSigningKeyId, OwnedUserId, PrivOwnedStr, RoomVersionId,
|
||||
UserId,
|
||||
};
|
||||
|
||||
mod change;
|
||||
|
||||
use self::change::membership_change;
|
||||
pub use self::change::{MembershipChange, MembershipDetails};
|
||||
|
||||
/// The content of an `m.room.member` event.
|
||||
///
|
||||
/// The current membership state of a user in the room.
|
||||
@ -293,101 +297,6 @@ impl SignedContent {
|
||||
}
|
||||
}
|
||||
|
||||
/// The details of a member event required to calculate a [`MembershipChange`].
|
||||
pub struct MembershipDetails<'a> {
|
||||
// These fields are intentionally private, this struct is only meant for
|
||||
// passing it to one of the membership_change methods on redacted events.
|
||||
avatar_url: Option<&'a MxcUri>,
|
||||
displayname: Option<&'a str>,
|
||||
membership: &'a MembershipState,
|
||||
}
|
||||
|
||||
/// Translation of the membership change in `m.room.member` event.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
pub enum MembershipChange {
|
||||
/// No change.
|
||||
None,
|
||||
|
||||
/// Must never happen.
|
||||
Error,
|
||||
|
||||
/// User joined the room.
|
||||
Joined,
|
||||
|
||||
/// User left the room.
|
||||
Left,
|
||||
|
||||
/// User was banned.
|
||||
Banned,
|
||||
|
||||
/// User was unbanned.
|
||||
Unbanned,
|
||||
|
||||
/// User was kicked.
|
||||
Kicked,
|
||||
|
||||
/// User was invited.
|
||||
Invited,
|
||||
|
||||
/// User was kicked and banned.
|
||||
KickedAndBanned,
|
||||
|
||||
/// User rejected the invite.
|
||||
InvitationRejected,
|
||||
|
||||
/// User had their invite revoked.
|
||||
InvitationRevoked,
|
||||
|
||||
/// `displayname` or `avatar_url` changed.
|
||||
ProfileChanged {
|
||||
/// Whether the `displayname` changed.
|
||||
displayname_changed: bool,
|
||||
|
||||
/// Whether the `avatar_url` changed.
|
||||
avatar_url_changed: bool,
|
||||
},
|
||||
|
||||
/// Not implemented.
|
||||
NotImplemented,
|
||||
}
|
||||
|
||||
/// Internal function so all `RoomMemberEventContent` state event kinds can share the same
|
||||
/// implementation.
|
||||
fn membership_change(
|
||||
details: MembershipDetails<'_>,
|
||||
prev_details: Option<MembershipDetails<'_>>,
|
||||
sender: &UserId,
|
||||
state_key: &UserId,
|
||||
) -> MembershipChange {
|
||||
use MembershipChange as Ch;
|
||||
use MembershipState as St;
|
||||
|
||||
let prev_details = match prev_details {
|
||||
Some(prev) => prev,
|
||||
None => MembershipDetails { avatar_url: None, displayname: None, membership: &St::Leave },
|
||||
};
|
||||
|
||||
match (&prev_details.membership, &details.membership) {
|
||||
(St::Invite, St::Invite) | (St::Leave, St::Leave) | (St::Ban, St::Ban) => Ch::None,
|
||||
(St::Invite, St::Join) | (St::Leave, St::Join) => Ch::Joined,
|
||||
(St::Invite, St::Leave) if sender == state_key => Ch::InvitationRevoked,
|
||||
(St::Invite, St::Leave) => Ch::InvitationRejected,
|
||||
(St::Invite, St::Ban) | (St::Leave, St::Ban) => Ch::Banned,
|
||||
(St::Join, St::Invite) | (St::Ban, St::Invite) | (St::Ban, St::Join) => Ch::Error,
|
||||
(St::Join, St::Join) => Ch::ProfileChanged {
|
||||
displayname_changed: prev_details.displayname != details.displayname,
|
||||
avatar_url_changed: prev_details.avatar_url != details.avatar_url,
|
||||
},
|
||||
(St::Join, St::Leave) if sender == state_key => Ch::Left,
|
||||
(St::Join, St::Leave) => Ch::Kicked,
|
||||
(St::Join, St::Ban) => Ch::KickedAndBanned,
|
||||
(St::Leave, St::Invite) => Ch::Invited,
|
||||
(St::Ban, St::Leave) => Ch::Unbanned,
|
||||
_ => Ch::NotImplemented,
|
||||
}
|
||||
}
|
||||
|
||||
impl OriginalRoomMemberEvent {
|
||||
/// Obtain the details about this event that are required to calculate a membership change.
|
||||
///
|
||||
|
97
crates/ruma-common/src/events/room/member/change.rs
Normal file
97
crates/ruma-common/src/events/room/member/change.rs
Normal file
@ -0,0 +1,97 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::MembershipState;
|
||||
use crate::{MxcUri, UserId};
|
||||
|
||||
/// The details of a member event required to calculate a [`MembershipChange`].
|
||||
pub struct MembershipDetails<'a> {
|
||||
pub(crate) avatar_url: Option<&'a MxcUri>,
|
||||
pub(crate) displayname: Option<&'a str>,
|
||||
pub(crate) membership: &'a MembershipState,
|
||||
}
|
||||
|
||||
/// Translation of the membership change in `m.room.member` event.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
pub enum MembershipChange {
|
||||
/// No change.
|
||||
None,
|
||||
|
||||
/// Must never happen.
|
||||
Error,
|
||||
|
||||
/// User joined the room.
|
||||
Joined,
|
||||
|
||||
/// User left the room.
|
||||
Left,
|
||||
|
||||
/// User was banned.
|
||||
Banned,
|
||||
|
||||
/// User was unbanned.
|
||||
Unbanned,
|
||||
|
||||
/// User was kicked.
|
||||
Kicked,
|
||||
|
||||
/// User was invited.
|
||||
Invited,
|
||||
|
||||
/// User was kicked and banned.
|
||||
KickedAndBanned,
|
||||
|
||||
/// User rejected the invite.
|
||||
InvitationRejected,
|
||||
|
||||
/// User had their invite revoked.
|
||||
InvitationRevoked,
|
||||
|
||||
/// `displayname` or `avatar_url` changed.
|
||||
ProfileChanged {
|
||||
/// Whether the `displayname` changed.
|
||||
displayname_changed: bool,
|
||||
|
||||
/// Whether the `avatar_url` changed.
|
||||
avatar_url_changed: bool,
|
||||
},
|
||||
|
||||
/// Not implemented.
|
||||
NotImplemented,
|
||||
}
|
||||
|
||||
/// Internal function so all `RoomMemberEventContent` state event kinds can share the same
|
||||
/// implementation.
|
||||
pub(super) fn membership_change(
|
||||
details: MembershipDetails<'_>,
|
||||
prev_details: Option<MembershipDetails<'_>>,
|
||||
sender: &UserId,
|
||||
state_key: &UserId,
|
||||
) -> MembershipChange {
|
||||
use MembershipChange as Ch;
|
||||
use MembershipState as St;
|
||||
|
||||
let prev_details = match prev_details {
|
||||
Some(prev) => prev,
|
||||
None => MembershipDetails { avatar_url: None, displayname: None, membership: &St::Leave },
|
||||
};
|
||||
|
||||
match (&prev_details.membership, &details.membership) {
|
||||
(St::Invite, St::Invite) | (St::Leave, St::Leave) | (St::Ban, St::Ban) => Ch::None,
|
||||
(St::Invite, St::Join) | (St::Leave, St::Join) => Ch::Joined,
|
||||
(St::Invite, St::Leave) if sender == state_key => Ch::InvitationRevoked,
|
||||
(St::Invite, St::Leave) => Ch::InvitationRejected,
|
||||
(St::Invite, St::Ban) | (St::Leave, St::Ban) => Ch::Banned,
|
||||
(St::Join, St::Invite) | (St::Ban, St::Invite) | (St::Ban, St::Join) => Ch::Error,
|
||||
(St::Join, St::Join) => Ch::ProfileChanged {
|
||||
displayname_changed: prev_details.displayname != details.displayname,
|
||||
avatar_url_changed: prev_details.avatar_url != details.avatar_url,
|
||||
},
|
||||
(St::Join, St::Leave) if sender == state_key => Ch::Left,
|
||||
(St::Join, St::Leave) => Ch::Kicked,
|
||||
(St::Join, St::Ban) => Ch::KickedAndBanned,
|
||||
(St::Leave, St::Invite) => Ch::Invited,
|
||||
(St::Ban, St::Leave) => Ch::Unbanned,
|
||||
_ => Ch::NotImplemented,
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user