Add membership_change method to stub and stripped event

Fix redaction event detection in event_enum! macro. Add encrypted event
to AnyMessageEvent enum.
This commit is contained in:
Devin R 2020-06-23 19:12:23 -04:00 committed by Jonas Platte
parent fdf87a38a2
commit 2b6eba69dd
3 changed files with 71 additions and 42 deletions

View File

@ -218,7 +218,7 @@ fn to_event_path(name: &LitStr, struct_name: &Ident) -> TokenStream {
let path = path.iter().map(|s| Ident::new(s, span)); let path = path.iter().map(|s| Ident::new(s, span));
match struct_name.to_string().as_str() { match struct_name.to_string().as_str() {
"MessageEvent" | "MessageEventStub" if *event_str == "m.room.redaction" => { "MessageEvent" | "MessageEventStub" if name == "m.room.redaction" => {
let redaction = if struct_name == "MessageEvent" { let redaction = if struct_name == "MessageEvent" {
quote! { RedactionEvent } quote! { RedactionEvent }
} else { } else {

View File

@ -36,6 +36,7 @@ event_enum! {
"m.call.invite", "m.call.invite",
"m.call.hangup", "m.call.hangup",
"m.call.candidates", "m.call.candidates",
"m.room.encrypted",
"m.room.message", "m.room.message",
"m.room.message.feedback", "m.room.message.feedback",
"m.room.redaction", "m.room.redaction",

View File

@ -7,7 +7,7 @@ use ruma_identifiers::UserId;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use strum::{Display, EnumString}; use strum::{Display, EnumString};
use crate::StateEvent; use crate::{StateEvent, StateEventStub, StrippedStateEventStub};
/// The current membership state of a user in the room. /// The current membership state of a user in the room.
/// ///
@ -162,52 +162,80 @@ pub enum MembershipChange {
NotImplemented, NotImplemented,
} }
/// Internal function so all `MemberEventContent` state event kinds can share the same implementation.
fn membership_change(
content: &MemberEventContent,
prev_content: Option<&MemberEventContent>,
sender: &UserId,
state_key: &str,
) -> MembershipChange {
use MembershipState::*;
let prev_content = if let Some(prev_content) = &prev_content {
prev_content
} else {
&MemberEventContent {
avatar_url: None,
displayname: None,
is_direct: None,
membership: Leave,
third_party_invite: None,
}
};
match (prev_content.membership, &content.membership) {
(Invite, Invite) | (Leave, Leave) | (Ban, Ban) => MembershipChange::None,
(Invite, Join) | (Leave, Join) => MembershipChange::Joined,
(Invite, Leave) => {
if sender.as_ref() == state_key {
MembershipChange::InvitationRevoked
} else {
MembershipChange::InvitationRejected
}
}
(Invite, Ban) | (Leave, Ban) => MembershipChange::Banned,
(Join, Invite) | (Ban, Invite) | (Ban, Join) => MembershipChange::Error,
(Join, Join) => MembershipChange::ProfileChanged {
displayname_changed: prev_content.displayname != content.displayname,
avatar_url_changed: prev_content.avatar_url != content.avatar_url,
},
(Join, Leave) => {
if sender.as_ref() == state_key {
MembershipChange::Left
} else {
MembershipChange::Kicked
}
}
(Join, Ban) => MembershipChange::KickedAndBanned,
(Leave, Invite) => MembershipChange::Invited,
(Ban, Leave) => MembershipChange::Unbanned,
(Knock, _) | (_, Knock) => MembershipChange::NotImplemented,
}
}
impl MemberEvent { impl MemberEvent {
/// Helper function for membership change. Check [the specification][spec] for details. /// Helper function for membership change. Check [the specification][spec] for details.
/// ///
/// [spec]: https://matrix.org/docs/spec/client_server/latest#m-room-member /// [spec]: https://matrix.org/docs/spec/client_server/latest#m-room-member
pub fn membership_change(&self) -> MembershipChange { pub fn membership_change(&self) -> MembershipChange {
use MembershipState::*; membership_change(&self.content, self.prev_content.as_ref(), &self.sender, &self.state_key)
let prev_content = if let Some(prev_content) = &self.prev_content { }
prev_content }
} else {
&MemberEventContent {
avatar_url: None,
displayname: None,
is_direct: None,
membership: Leave,
third_party_invite: None,
}
};
match (prev_content.membership, &self.content.membership) { impl StateEventStub<MemberEventContent> {
(Invite, Invite) | (Leave, Leave) | (Ban, Ban) => MembershipChange::None, /// Helper function for membership change. Check [the specification][spec] for details.
(Invite, Join) | (Leave, Join) => MembershipChange::Joined, ///
(Invite, Leave) => { /// [spec]: https://matrix.org/docs/spec/client_server/latest#m-room-member
if self.sender == self.state_key { pub fn membership_change(&self) -> MembershipChange {
MembershipChange::InvitationRevoked membership_change(&self.content, self.prev_content.as_ref(), &self.sender, &self.state_key)
} else { }
MembershipChange::InvitationRejected }
}
} impl StrippedStateEventStub<MemberEventContent> {
(Invite, Ban) | (Leave, Ban) => MembershipChange::Banned, /// Helper function for membership change. Check [the specification][spec] for details.
(Join, Invite) | (Ban, Invite) | (Ban, Join) => MembershipChange::Error, ///
(Join, Join) => MembershipChange::ProfileChanged { /// [spec]: https://matrix.org/docs/spec/client_server/latest#m-room-member
displayname_changed: prev_content.displayname != self.content.displayname, pub fn membership_change(&self) -> MembershipChange {
avatar_url_changed: prev_content.avatar_url != self.content.avatar_url, membership_change(&self.content, None, &self.sender, &self.state_key)
},
(Join, Leave) => {
if self.sender == self.state_key {
MembershipChange::Left
} else {
MembershipChange::Kicked
}
}
(Join, Ban) => MembershipChange::KickedAndBanned,
(Leave, Invite) => MembershipChange::Invited,
(Ban, Leave) => MembershipChange::Unbanned,
(Knock, _) | (_, Knock) => MembershipChange::NotImplemented,
}
} }
} }