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,
|
serde::StringEnum,
|
||||||
MxcUri, OwnedServerName, OwnedServerSigningKeyId, OwnedUserId, PrivOwnedStr, RoomVersionId,
|
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 content of an `m.room.member` event.
|
||||||
///
|
///
|
||||||
/// The current membership state of a user in the room.
|
/// 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 {
|
impl OriginalRoomMemberEvent {
|
||||||
/// Obtain the details about this event that are required to calculate a membership change.
|
/// 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