From d82e2a02d543f79e93802291907bbec9da78ecc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 26 Nov 2024 16:08:32 +0100 Subject: [PATCH] events: Add support for MSC4171 --- crates/ruma-events/CHANGELOG.md | 4 + crates/ruma-events/Cargo.toml | 1 + crates/ruma-events/src/enums.rs | 3 + crates/ruma-events/src/lib.rs | 2 + crates/ruma-events/src/member_hints.rs | 113 +++++++++++++++++++++++++ crates/ruma/Cargo.toml | 2 + 6 files changed, 125 insertions(+) create mode 100644 crates/ruma-events/src/member_hints.rs diff --git a/crates/ruma-events/CHANGELOG.md b/crates/ruma-events/CHANGELOG.md index 5d3efa9b..f2cbe553 100644 --- a/crates/ruma-events/CHANGELOG.md +++ b/crates/ruma-events/CHANGELOG.md @@ -1,5 +1,9 @@ # [unreleased] +Improvements: + +- Add unstable support for MSC4171 for the m.member_hints state event. + Breaking changes: - Take newly introduced `DirectUserIdentifier(str)` as a key for `DirectEventContent`. diff --git a/crates/ruma-events/Cargo.toml b/crates/ruma-events/Cargo.toml index 9a34235f..3e868551 100644 --- a/crates/ruma-events/Cargo.toml +++ b/crates/ruma-events/Cargo.toml @@ -43,6 +43,7 @@ unstable-msc3955 = ["unstable-msc1767"] unstable-msc3956 = ["unstable-msc1767"] unstable-msc4075 = ["unstable-msc3401"] unstable-msc4095 = [] +unstable-msc4171 = [] unstable-pdu = [] # Allow some mandatory fields to be missing, defaulting them to an empty string diff --git a/crates/ruma-events/src/enums.rs b/crates/ruma-events/src/enums.rs index 3a7b214f..a481c7b4 100644 --- a/crates/ruma-events/src/enums.rs +++ b/crates/ruma-events/src/enums.rs @@ -138,6 +138,9 @@ event_enum! { "org.matrix.msc3401.call.member" => super::call::member, #[ruma_enum(alias = "m.room.preview_urls")] "org.matrix.room.preview_urls" => super::room::preview_url, + #[cfg(feature = "unstable-msc4171")] + #[ruma_enum(alias = "m.member_hints")] + "io.element.functional_members" => super::member_hints, } /// Any to-device event. diff --git a/crates/ruma-events/src/lib.rs b/crates/ruma-events/src/lib.rs index 108768f7..57fdd060 100644 --- a/crates/ruma-events/src/lib.rs +++ b/crates/ruma-events/src/lib.rs @@ -162,6 +162,8 @@ pub mod key; #[cfg(feature = "unstable-msc3488")] pub mod location; pub mod marked_unread; +#[cfg(feature = "unstable-msc4171")] +pub mod member_hints; #[cfg(feature = "unstable-msc1767")] pub mod message; #[cfg(feature = "unstable-pdu")] diff --git a/crates/ruma-events/src/member_hints.rs b/crates/ruma-events/src/member_hints.rs new file mode 100644 index 00000000..84a0270c --- /dev/null +++ b/crates/ruma-events/src/member_hints.rs @@ -0,0 +1,113 @@ +//! Types for Matrix member hint state events ([MSC4171]). +//! +//! This implements `m.member_hints` state event described in [MSC4171]. +//! +//! [MSC4171]: https://github.com/matrix-org/matrix-spec-proposals/pull/4171 + +use std::collections::BTreeSet; + +use ruma_common::OwnedUserId; +use ruma_macros::EventContent; +use serde::{Deserialize, Serialize}; + +use crate::EmptyStateKey; + +/// The content for an `m.member_hints` state event. +/// +/// Any users (service members) listed in the content should not be considered when computing the +/// room name or avatar based on the member list. +#[derive(Clone, Debug, Default, Serialize, Deserialize, EventContent, PartialEq)] +#[ruma_event(type = "io.element.functional_members", kind = State, state_key_type = EmptyStateKey)] +#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] +pub struct MemberHintsEventContent { + /// The list of user IDs that should be considered a service member of the room. + pub service_members: BTreeSet, +} + +impl MemberHintsEventContent { + /// Create a new [`MemberHintsEventContent`] with the given set of service members. + pub fn new(service_members: BTreeSet) -> Self { + Self { service_members } + } +} + +#[cfg(test)] +mod test { + use std::collections::BTreeSet; + + use assert_matches2::assert_matches; + use ruma_common::user_id; + use serde_json::{from_value as from_json_value, json}; + + use super::*; + use crate::AnyStateEvent; + + #[test] + fn deserialize() { + let user_id = user_id!("@slackbot:matrix.org"); + + let data = json!({ + "type": "io.element.functional_members", + "state_key": "", + "content": { + "service_members": [ + user_id, + ] + }, + "origin_server_ts": 111, + "event_id": "$3qfxjGYSu4sL25FtR0ep6vePOc", + "room_id": "!1234:example.org", + "sender": "@user:example.org" + }); + + let event = from_json_value::(data) + .expect("We should be able to deserialize the member hints event"); + + assert_matches!(event, AnyStateEvent::MemberHints(event)); + assert_matches!(event, crate::StateEvent::Original(event)); + + assert!(event.content.service_members.contains(user_id)); + + let data = json!({ + "type": "m.member_hints", + "state_key": "", + "content": { + "service_members": [ + user_id, + ] + }, + "origin_server_ts": 111, + "event_id": "$3qfxjGYSu4sL25FtR0ep6vePOc", + "room_id": "!1234:example.org", + "sender": "@user:example.org" + }); + + let event = from_json_value::(data) + .expect("We should be able to deserialize the member hints event"); + + assert_matches!(event, AnyStateEvent::MemberHints(event)); + assert_matches!(event, crate::StateEvent::Original(event)); + + assert!(event.content.service_members.contains(user_id)); + } + + #[test] + fn serialize() { + let user_id = user_id!("@slackbot:matrix.org"); + let content = MemberHintsEventContent::new(BTreeSet::from([user_id.to_owned()])); + + let serialized = serde_json::to_value(content) + .expect("We should be able to serialize the member hints content"); + + let expected = json!({ + "service_members": [ + user_id, + ] + }); + + assert_eq!( + expected, serialized, + "The serialized member hints content should match the expected one" + ); + } +} diff --git a/crates/ruma/Cargo.toml b/crates/ruma/Cargo.toml index ce196656..d3e03694 100644 --- a/crates/ruma/Cargo.toml +++ b/crates/ruma/Cargo.toml @@ -270,6 +270,7 @@ unstable-msc4108 = ["ruma-client-api?/unstable-msc4108"] unstable-msc4121 = ["ruma-client-api?/unstable-msc4121"] unstable-msc4125 = ["ruma-federation-api?/unstable-msc4125"] unstable-msc4140 = ["ruma-client-api?/unstable-msc4140"] +unstable-msc4171 = ["ruma-events?/unstable-msc4171"] unstable-msc4186 = ["ruma-client-api?/unstable-msc4186"] unstable-msc4210 = ["ruma-common/unstable-msc4210"] unstable-pdu = ["ruma-events?/unstable-pdu"] @@ -324,6 +325,7 @@ __unstable-mscs = [ "unstable-msc4121", "unstable-msc4125", "unstable-msc4140", + "unstable-msc4171", "unstable-msc4186", ] __ci = [