ruma_events/
member_hints.rs

1//! Types for Matrix member hint state events ([MSC4171]).
2//!
3//! This implements `m.member_hints` state event described in [MSC4171].
4//!
5//! [MSC4171]: https://github.com/matrix-org/matrix-spec-proposals/pull/4171
6
7use std::collections::BTreeSet;
8
9use ruma_common::OwnedUserId;
10use ruma_macros::EventContent;
11use serde::{Deserialize, Serialize};
12
13use crate::EmptyStateKey;
14
15/// The content for an `m.member_hints` state event.
16///
17/// Any users (service members) listed in the content should not be considered when computing the
18/// room name or avatar based on the member list.
19#[derive(Clone, Debug, Default, Serialize, Deserialize, EventContent, PartialEq)]
20#[ruma_event(type = "io.element.functional_members", kind = State, state_key_type = EmptyStateKey)]
21#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
22pub struct MemberHintsEventContent {
23    /// The list of user IDs that should be considered a service member of the room.
24    pub service_members: BTreeSet<OwnedUserId>,
25}
26
27impl MemberHintsEventContent {
28    /// Create a new [`MemberHintsEventContent`] with the given set of service members.
29    pub fn new(service_members: BTreeSet<OwnedUserId>) -> Self {
30        Self { service_members }
31    }
32}
33
34#[cfg(test)]
35mod test {
36    use std::collections::BTreeSet;
37
38    use assert_matches2::assert_matches;
39    use ruma_common::user_id;
40    use serde_json::{from_value as from_json_value, json};
41
42    use super::*;
43    use crate::AnyStateEvent;
44
45    #[test]
46    fn deserialize() {
47        let user_id = user_id!("@slackbot:matrix.org");
48
49        let data = json!({
50            "type": "io.element.functional_members",
51            "state_key": "",
52            "content": {
53                "service_members": [
54                    user_id,
55                ]
56            },
57            "origin_server_ts": 111,
58            "event_id": "$3qfxjGYSu4sL25FtR0ep6vePOc",
59            "room_id": "!1234:example.org",
60            "sender": "@user:example.org"
61        });
62
63        let event = from_json_value::<AnyStateEvent>(data)
64            .expect("We should be able to deserialize the member hints event");
65
66        assert_matches!(event, AnyStateEvent::MemberHints(event));
67        assert_matches!(event, crate::StateEvent::Original(event));
68
69        assert!(event.content.service_members.contains(user_id));
70
71        let data = json!({
72            "type": "m.member_hints",
73            "state_key": "",
74            "content": {
75                "service_members": [
76                    user_id,
77                ]
78            },
79            "origin_server_ts": 111,
80            "event_id": "$3qfxjGYSu4sL25FtR0ep6vePOc",
81            "room_id": "!1234:example.org",
82            "sender": "@user:example.org"
83        });
84
85        let event = from_json_value::<AnyStateEvent>(data)
86            .expect("We should be able to deserialize the member hints event");
87
88        assert_matches!(event, AnyStateEvent::MemberHints(event));
89        assert_matches!(event, crate::StateEvent::Original(event));
90
91        assert!(event.content.service_members.contains(user_id));
92    }
93
94    #[test]
95    fn serialize() {
96        let user_id = user_id!("@slackbot:matrix.org");
97        let content = MemberHintsEventContent::new(BTreeSet::from([user_id.to_owned()]));
98
99        let serialized = serde_json::to_value(content)
100            .expect("We should be able to serialize the member hints content");
101
102        let expected = json!({
103            "service_members": [
104                user_id,
105            ]
106        });
107
108        assert_eq!(
109            expected, serialized,
110            "The serialized member hints content should match the expected one"
111        );
112    }
113}