ruma_events/
invite_permission_config.rs

1//! Types for the [`m.invite_permission_config`] account data.
2//!
3//! [`m.invite_permission_config`]: https://github.com/matrix-org/matrix-spec-proposals/pull/4380
4
5use ruma_macros::{EventContent, StringEnum};
6use serde::{Deserialize, Serialize};
7
8use crate::PrivOwnedStr;
9
10/// The content of an [`m.invite_permission_config`] account data.
11///
12/// Controls whether invites to this account are permitted.
13///
14/// [`m.invite_permission_config`]: https://github.com/matrix-org/matrix-spec-proposals/pull/4380
15#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)]
16#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
17#[ruma_event(
18    kind = GlobalAccountData,
19    type = "m.invite_permission_config",
20)]
21pub struct InvitePermissionConfigEventContent {
22    /// The default action chosen by the user that the homeserver should perform automatically when
23    /// receiving an invitation for this account.
24    ///
25    /// A missing, invalid or unsupported value means that the user wants to receive invites as
26    /// normal. Other parts of the specification might still have effects on invites, like
27    /// [ignoring users].
28    ///
29    /// [ignoring users]: https://spec.matrix.org/latest/client-server-api/#ignoring-users
30    #[serde(
31        default,
32        deserialize_with = "ruma_common::serde::default_on_error",
33        skip_serializing_if = "Option::is_none"
34    )]
35    pub default_action: Option<InvitePermissionAction>,
36}
37
38impl InvitePermissionConfigEventContent {
39    /// Creates a new empty `InvitePermissionConfigEventContent`.
40    pub fn new() -> Self {
41        Self::default()
42    }
43}
44
45/// Possible actions in response to an invite.
46#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
47#[derive(Clone, StringEnum)]
48#[ruma_enum(rename_all = "lowercase")]
49#[non_exhaustive]
50pub enum InvitePermissionAction {
51    /// Reject the invite.
52    Block,
53
54    #[doc(hidden)]
55    _Custom(PrivOwnedStr),
56}
57
58/// The content of an [`org.matrix.msc4380.invite_permission_config`][MSC4380] account data, the
59/// unstable version of [`InvitePermissionConfigEventContent`].
60///
61/// Controls whether invites to this account are permitted.
62///
63/// [MSC4380]: https://github.com/matrix-org/matrix-spec-proposals/pull/4380
64#[cfg(feature = "unstable-msc4380")]
65#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)]
66#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
67#[ruma_event(
68    kind = GlobalAccountData,
69    type = "org.matrix.msc4380.invite_permission_config",
70)]
71pub struct UnstableInvitePermissionConfigEventContent {
72    /// When set to true, indicates that the user does not wish to receive *any* room invites, and
73    /// they should be blocked.
74    #[serde(default, deserialize_with = "ruma_common::serde::default_on_error")]
75    pub block_all: bool,
76}
77
78#[cfg(feature = "unstable-msc4380")]
79impl UnstableInvitePermissionConfigEventContent {
80    /// Creates a new `UnstableInvitePermissionConfigEventContent` from the desired boolean state.
81    pub fn new(block_all: bool) -> Self {
82        Self { block_all }
83    }
84}
85
86#[cfg(feature = "unstable-msc4380")]
87impl From<UnstableInvitePermissionConfigEventContent> for InvitePermissionConfigEventContent {
88    fn from(value: UnstableInvitePermissionConfigEventContent) -> Self {
89        Self { default_action: value.block_all.then_some(InvitePermissionAction::Block) }
90    }
91}
92
93#[cfg(feature = "unstable-msc4380")]
94impl From<InvitePermissionConfigEventContent> for UnstableInvitePermissionConfigEventContent {
95    fn from(value: InvitePermissionConfigEventContent) -> Self {
96        Self {
97            block_all: value
98                .default_action
99                .is_some_and(|action| matches!(action, InvitePermissionAction::Block)),
100        }
101    }
102}
103
104#[cfg(test)]
105mod tests {
106    use assert_matches2::assert_matches;
107    use ruma_common::canonical_json::assert_to_canonical_json_eq;
108    use serde_json::{from_value as from_json_value, json};
109
110    #[cfg(feature = "unstable-msc4380")]
111    use super::UnstableInvitePermissionConfigEventContent;
112    use super::{InvitePermissionAction, InvitePermissionConfigEventContent};
113    use crate::AnyGlobalAccountDataEvent;
114
115    #[cfg(feature = "unstable-msc4380")]
116    #[test]
117    fn unstable_serialization() {
118        let invite_permission_config = UnstableInvitePermissionConfigEventContent::new(true);
119
120        assert_to_canonical_json_eq!(
121            invite_permission_config,
122            json!({
123                "block_all": true,
124            }),
125        );
126    }
127
128    #[cfg(feature = "unstable-msc4380")]
129    #[test]
130    fn unstable_deserialization() {
131        let json = json!({
132            "content": {
133                "block_all": true,
134            },
135            "type": "org.matrix.msc4380.invite_permission_config",
136        });
137
138        assert_matches!(
139            from_json_value::<AnyGlobalAccountDataEvent>(json),
140            Ok(AnyGlobalAccountDataEvent::UnstableInvitePermissionConfig(ev))
141        );
142        assert!(ev.content.block_all);
143    }
144
145    #[test]
146    fn stable_serialization() {
147        let mut invite_permission_config = InvitePermissionConfigEventContent::new();
148        assert_to_canonical_json_eq!(invite_permission_config, json!({}),);
149
150        invite_permission_config.default_action = Some(InvitePermissionAction::Block);
151        assert_to_canonical_json_eq!(
152            invite_permission_config,
153            json!({
154                "default_action": "block",
155            }),
156        );
157    }
158
159    #[test]
160    fn stable_deserialization() {
161        let json = json!({
162            "content": {
163                "default_action": "block",
164            },
165            "type": "m.invite_permission_config",
166        });
167        assert_matches!(
168            from_json_value::<AnyGlobalAccountDataEvent>(json),
169            Ok(AnyGlobalAccountDataEvent::InvitePermissionConfig(ev))
170        );
171        assert_eq!(ev.content.default_action, Some(InvitePermissionAction::Block));
172
173        let json = json!({
174            "content": {},
175            "type": "m.invite_permission_config",
176        });
177        assert_matches!(
178            from_json_value::<AnyGlobalAccountDataEvent>(json),
179            Ok(AnyGlobalAccountDataEvent::InvitePermissionConfig(ev))
180        );
181        assert_eq!(ev.content.default_action, None);
182    }
183}