ruma_events/room/
join_rules.rs1pub use ruma_common::room::{AllowRule, JoinRule, Restricted};
6use ruma_macros::EventContent;
7use serde::{de, Deserialize, Serialize};
8
9use crate::EmptyStateKey;
10
11#[derive(Clone, Debug, Serialize, EventContent)]
15#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
16#[ruma_event(type = "m.room.join_rules", kind = State, state_key_type = EmptyStateKey)]
17pub struct RoomJoinRulesEventContent {
18 #[ruma_event(skip_redaction)]
20 #[serde(flatten)]
21 pub join_rule: JoinRule,
22}
23
24impl RoomJoinRulesEventContent {
25 pub fn new(join_rule: JoinRule) -> Self {
27 Self { join_rule }
28 }
29
30 pub fn restricted(allow: Vec<AllowRule>) -> Self {
33 Self { join_rule: JoinRule::Restricted(Restricted::new(allow)) }
34 }
35
36 pub fn knock_restricted(allow: Vec<AllowRule>) -> Self {
39 Self { join_rule: JoinRule::KnockRestricted(Restricted::new(allow)) }
40 }
41}
42
43impl<'de> Deserialize<'de> for RoomJoinRulesEventContent {
44 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
45 where
46 D: de::Deserializer<'de>,
47 {
48 let join_rule = JoinRule::deserialize(deserializer)?;
49 Ok(RoomJoinRulesEventContent { join_rule })
50 }
51}
52
53impl RoomJoinRulesEvent {
54 pub fn join_rule(&self) -> &JoinRule {
56 match self {
57 Self::Original(ev) => &ev.content.join_rule,
58 Self::Redacted(ev) => &ev.content.join_rule,
59 }
60 }
61}
62
63impl SyncRoomJoinRulesEvent {
64 pub fn join_rule(&self) -> &JoinRule {
66 match self {
67 Self::Original(ev) => &ev.content.join_rule,
68 Self::Redacted(ev) => &ev.content.join_rule,
69 }
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use assert_matches2::assert_matches;
76 use ruma_common::owned_room_id;
77
78 use super::{AllowRule, JoinRule, OriginalSyncRoomJoinRulesEvent, RoomJoinRulesEventContent};
79
80 #[test]
81 fn deserialize() {
82 let json = r#"{"join_rule": "public"}"#;
83 let event: RoomJoinRulesEventContent = serde_json::from_str(json).unwrap();
84 assert_matches!(event, RoomJoinRulesEventContent { join_rule: JoinRule::Public });
85 }
86
87 #[test]
88 fn deserialize_restricted() {
89 let json = r#"{
90 "join_rule": "restricted",
91 "allow": [
92 {
93 "type": "m.room_membership",
94 "room_id": "!mods:example.org"
95 },
96 {
97 "type": "m.room_membership",
98 "room_id": "!users:example.org"
99 }
100 ]
101 }"#;
102 let event: RoomJoinRulesEventContent = serde_json::from_str(json).unwrap();
103 assert_matches!(event.join_rule, JoinRule::Restricted(restricted));
104 assert_eq!(
105 restricted.allow,
106 &[
107 AllowRule::room_membership(owned_room_id!("!mods:example.org")),
108 AllowRule::room_membership(owned_room_id!("!users:example.org"))
109 ]
110 );
111 }
112
113 #[test]
114 fn deserialize_restricted_event() {
115 let json = r#"{
116 "type": "m.room.join_rules",
117 "sender": "@admin:community.rs",
118 "content": {
119 "join_rule": "restricted",
120 "allow": [
121 { "type": "m.room_membership","room_id": "!KqeUnzmXPIhHRaWMTs:mccarty.io" }
122 ]
123 },
124 "state_key": "",
125 "origin_server_ts":1630508835342,
126 "unsigned": {
127 "age":4165521871
128 },
129 "event_id": "$0ACb9KSPlT3al3kikyRYvFhMqXPP9ZcQOBrsdIuh58U"
130 }"#;
131
132 assert_matches!(serde_json::from_str::<OriginalSyncRoomJoinRulesEvent>(json), Ok(_));
133 }
134
135 #[test]
136 fn restricted_room_no_allow_field() {
137 let json = r#"{"join_rule":"restricted"}"#;
138 let join_rules: RoomJoinRulesEventContent = serde_json::from_str(json).unwrap();
139 assert_matches!(
140 join_rules,
141 RoomJoinRulesEventContent { join_rule: JoinRule::Restricted(_) }
142 );
143 }
144}