tuwunel_service/rooms/state_res/events/
create.rs1use std::{borrow::Cow, iter, ops::Deref};
4
5use ruma::{
6 OwnedUserId, RoomVersionId, UserId, room_version_rules::AuthorizationRules,
7 serde::from_raw_json_value,
8};
9use serde::{Deserialize, de::IgnoredAny};
10use tuwunel_core::{Error, Result, err, matrix::Event};
11
12#[derive(Debug)]
16pub struct RoomCreateEvent<E: Event>(E);
17
18impl<E: Event> RoomCreateEvent<E> {
19 #[inline]
21 pub fn new(event: E) -> Self { Self(event) }
22
23 pub fn room_version(&self) -> Result<RoomVersionId> {
25 #[derive(Deserialize)]
26 struct RoomCreateContentRoomVersion {
27 room_version: Option<RoomVersionId>,
28 }
29
30 let content: RoomCreateContentRoomVersion =
31 from_raw_json_value(self.content()).map_err(|err: Error| {
32 err!("invalid `room_version` field in `m.room.create` event: {err}")
33 })?;
34
35 Ok(content.room_version.unwrap_or(RoomVersionId::V1))
36 }
37
38 pub fn federate(&self) -> Result<bool> {
40 #[derive(Deserialize)]
41 struct RoomCreateContentFederate {
42 #[serde(rename = "m.federate")]
43 federate: Option<bool>,
44 }
45
46 let content: RoomCreateContentFederate =
47 from_raw_json_value(self.content()).map_err(|err: Error| {
48 err!("invalid `m.federate` field in `m.room.create` event: {err}")
49 })?;
50
51 Ok(content.federate.unwrap_or(true))
52 }
53
54 pub fn creator(&self, rules: &AuthorizationRules) -> Result<Cow<'_, UserId>> {
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: Error| {
70 err!("missing or invalid `creator` field in `m.room.create` event: {err}")
71 })?;
72
73 Ok(Cow::Owned(content.creator))
74 }
75 }
76
77 pub fn creators<'a>(
86 &'a self,
87 rules: &'a AuthorizationRules,
88 ) -> Result<impl Iterator<Item = OwnedUserId> + Clone + use<'a, E>> {
89 let initial = self.creator(rules)?.into_owned();
90 let additional = self.additional_creators(rules)?;
91
92 Ok(iter::once(initial).chain(additional))
93 }
94
95 pub(super) fn additional_creators(
105 &self,
106 rules: &AuthorizationRules,
107 ) -> Result<impl Iterator<Item = OwnedUserId> + Clone> {
108 #[derive(Deserialize)]
109 struct RoomCreateContentAdditionalCreators {
110 #[serde(default)]
111 additional_creators: Vec<OwnedUserId>,
112 }
113
114 Ok(if rules.additional_room_creators {
115 let mut content: RoomCreateContentAdditionalCreators =
116 from_raw_json_value(self.content()).map_err(|err: serde_json::Error| {
117 err!("invalid `additional_creators` field in `m.room.create` event: {err}")
118 })?;
119
120 content.additional_creators.sort();
121 content.additional_creators.dedup();
122 content.additional_creators.into_iter()
123 } else {
124 Vec::new().into_iter()
125 })
126 }
127
128 pub fn has_creator(&self) -> Result<bool> {
130 #[derive(Deserialize)]
131 struct RoomCreateContentCreator {
132 creator: Option<IgnoredAny>,
133 }
134
135 let content: RoomCreateContentCreator =
136 from_raw_json_value(self.content()).map_err(|err: Error| {
137 err!("invalid `creator` field in `m.room.create` event: {err}")
138 })?;
139
140 Ok(content.creator.is_some())
141 }
142}
143
144impl<E: Event> Deref for RoomCreateEvent<E> {
145 type Target = E;
146
147 #[inline]
148 fn deref(&self) -> &Self::Target { &self.0 }
149}