ruma_state_res/events/
create.rs

1//! Types to deserialize `m.room.create` events.
2
3use std::{borrow::Cow, 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    pub fn creator(&self, rules: &AuthorizationRules) -> Result<Cow<'_, UserId>, String> {
60        #[derive(Deserialize)]
61        struct RoomCreateContentCreator {
62            creator: OwnedUserId,
63        }
64
65        if rules.use_room_create_sender {
66            Ok(Cow::Borrowed(self.sender()))
67        } else {
68            let content: RoomCreateContentCreator =
69                from_raw_json_value(self.content()).map_err(|err: serde_json::Error| {
70                    format!("missing or invalid `creator` field in `m.room.create` event: {err}")
71                })?;
72
73            Ok(Cow::Owned(content.creator))
74        }
75    }
76
77    /// Whether the event has a `creator` field.
78    pub(crate) fn has_creator(&self) -> Result<bool, String> {
79        #[derive(Deserialize)]
80        struct RoomCreateContentCreator {
81            creator: Option<IgnoredAny>,
82        }
83
84        let content: RoomCreateContentCreator =
85            from_raw_json_value(self.content()).map_err(|err: serde_json::Error| {
86                format!("invalid `creator` field in `m.room.create` event: {err}")
87            })?;
88        Ok(content.creator.is_some())
89    }
90}
91
92impl<E: Event> Deref for RoomCreateEvent<E> {
93    type Target = E;
94
95    fn deref(&self) -> &Self::Target {
96        &self.0
97    }
98}