ruma_state_res/events/
create.rs

1//! Types to deserialize `m.room.create` events.
2
3use std::{borrow::Cow, collections::HashSet, ops::Deref};
4
5use ruma_common::{
6    room_version_rules::AuthorizationRules, serde::from_raw_json_value, OwnedUserId, RoomVersionId,
7    UserId,
8};
9use serde::{de::IgnoredAny, Deserialize};
10
11use super::Event;
12
13/// A helper type for an [`Event`] of type `m.room.create`.
14///
15/// This is a type that deserializes each field lazily, when requested.
16#[derive(Debug, Clone)]
17pub struct RoomCreateEvent<E: Event>(E);
18
19impl<E: Event> RoomCreateEvent<E> {
20    /// Construct a new `RoomCreateEvent` around the given event.
21    pub fn new(event: E) -> Self {
22        Self(event)
23    }
24
25    /// The version of the room.
26    pub fn room_version(&self) -> Result<RoomVersionId, String> {
27        #[derive(Deserialize)]
28        struct RoomCreateContentRoomVersion {
29            room_version: Option<RoomVersionId>,
30        }
31
32        let content: RoomCreateContentRoomVersion =
33            from_raw_json_value(self.content()).map_err(|err: serde_json::Error| {
34                format!("invalid `room_version` field in `m.room.create` event: {err}")
35            })?;
36        Ok(content.room_version.unwrap_or(RoomVersionId::V1))
37    }
38
39    /// Whether the room is federated.
40    pub fn federate(&self) -> Result<bool, String> {
41        #[derive(Deserialize)]
42        struct RoomCreateContentFederate {
43            #[serde(rename = "m.federate")]
44            federate: Option<bool>,
45        }
46
47        let content: RoomCreateContentFederate =
48            from_raw_json_value(self.content()).map_err(|err: serde_json::Error| {
49                format!("invalid `m.federate` field in `m.room.create` event: {err}")
50            })?;
51        Ok(content.federate.unwrap_or(true))
52    }
53
54    /// The creator of the room.
55    ///
56    /// If the `use_room_create_sender` field of `AuthorizationRules` is set, the creator is the
57    /// sender of this `m.room.create` event, otherwise it is deserialized from the `creator`
58    /// field of this event's content.
59    ///
60    /// This function ignores any `content.additional_creators`, and should only be used in
61    /// `check_room_member_join`. Otherwise, you should use `creators` instead.
62    pub(crate) fn creator(&self, rules: &AuthorizationRules) -> Result<Cow<'_, UserId>, String> {
63        #[derive(Deserialize)]
64        struct RoomCreateContentCreator {
65            creator: OwnedUserId,
66        }
67
68        if rules.use_room_create_sender {
69            Ok(Cow::Borrowed(self.sender()))
70        } else {
71            let content: RoomCreateContentCreator =
72                from_raw_json_value(self.content()).map_err(|err: serde_json::Error| {
73                    format!("missing or invalid `creator` field in `m.room.create` event: {err}")
74                })?;
75
76            Ok(Cow::Owned(content.creator))
77        }
78    }
79
80    /// The additional creators of the room (if any).
81    ///
82    /// If the `explicitly_privilege_room_creators`
83    /// field of `AuthorizationRules` is set, any additional user IDs in `additional_creators`, if
84    /// present, will also be considered creators.
85    ///
86    /// This function ignores the primary room creator, and should only be used in
87    /// `check_room_member_join`. Otherwise, you should use `creators` instead.
88    pub(crate) fn additional_creators(
89        &self,
90        rules: &AuthorizationRules,
91    ) -> Result<HashSet<OwnedUserId>, String> {
92        #[derive(Deserialize)]
93        struct RoomCreateContentAdditionalCreators {
94            #[serde(default)]
95            additional_creators: HashSet<OwnedUserId>,
96        }
97
98        Ok(if rules.additional_room_creators {
99            let content: RoomCreateContentAdditionalCreators = from_raw_json_value(self.content())
100                .map_err(|err: serde_json::Error| {
101                    format!("invalid `additional_creators` field in `m.room.create` event: {err}")
102                })?;
103
104            content.additional_creators
105        } else {
106            HashSet::new()
107        })
108    }
109
110    /// The creators of the room.
111    ///
112    /// If the `use_room_create_sender` field of `AuthorizationRules` is set, the creator is the
113    /// sender of this `m.room.create` event, otherwise it is deserialized from the `creator`
114    /// field of this event's content. Additionally if the `explicitly_privilege_room_creators`
115    /// field of `AuthorizationRules` is set, any additional user IDs in `additional_creators`, if
116    /// present, will also be considered creators.
117    pub fn creators(&self, rules: &AuthorizationRules) -> Result<HashSet<OwnedUserId>, String> {
118        let mut creators = self.additional_creators(rules)?;
119
120        creators.insert(self.creator(rules)?.into_owned());
121
122        Ok(creators)
123    }
124
125    /// Whether the event has a `creator` field.
126    pub(crate) fn has_creator(&self) -> Result<bool, String> {
127        #[derive(Deserialize)]
128        struct RoomCreateContentCreator {
129            creator: Option<IgnoredAny>,
130        }
131
132        let content: RoomCreateContentCreator =
133            from_raw_json_value(self.content()).map_err(|err: serde_json::Error| {
134                format!("invalid `creator` field in `m.room.create` event: {err}")
135            })?;
136        Ok(content.creator.is_some())
137    }
138}
139
140impl<E: Event> Deref for RoomCreateEvent<E> {
141    type Target = E;
142
143    fn deref(&self) -> &Self::Target {
144        &self.0
145    }
146}