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::{
11 Error, Result, err,
12 itertools::{Either, Itertools},
13 matrix::Event,
14};
15
16#[derive(Debug)]
20pub struct RoomCreateEvent<E: Event>(E);
21
22impl<E: Event> RoomCreateEvent<E> {
23 #[inline]
25 pub fn new(event: E) -> Self { Self(event) }
26
27 pub fn room_version(&self) -> Result<RoomVersionId> {
29 #[derive(Deserialize)]
30 struct RoomCreateContentRoomVersion {
31 room_version: Option<RoomVersionId>,
32 }
33
34 let content: RoomCreateContentRoomVersion =
35 from_raw_json_value(self.content()).map_err(|err: Error| {
36 err!("invalid `room_version` field in `m.room.create` event: {err}")
37 })?;
38
39 Ok(content.room_version.unwrap_or(RoomVersionId::V1))
40 }
41
42 pub fn federate(&self) -> Result<bool> {
44 #[derive(Deserialize)]
45 struct RoomCreateContentFederate {
46 #[serde(rename = "m.federate")]
47 federate: Option<bool>,
48 }
49
50 let content: RoomCreateContentFederate =
51 from_raw_json_value(self.content()).map_err(|err: Error| {
52 err!("invalid `m.federate` field in `m.room.create` event: {err}")
53 })?;
54
55 Ok(content.federate.unwrap_or(true))
56 }
57
58 pub fn creator(&self, rules: &AuthorizationRules) -> Result<Cow<'_, UserId>> {
64 #[derive(Deserialize)]
65 struct RoomCreateContentCreator {
66 creator: OwnedUserId,
67 }
68
69 if rules.use_room_create_sender {
70 Ok(Cow::Borrowed(self.sender()))
71 } else {
72 let content: RoomCreateContentCreator =
73 from_raw_json_value(self.content()).map_err(|err: Error| {
74 err!("missing or invalid `creator` field in `m.room.create` event: {err}")
75 })?;
76
77 Ok(Cow::Owned(content.creator))
78 }
79 }
80
81 pub fn creators<'a>(
90 &'a self,
91 rules: &'a AuthorizationRules,
92 ) -> Result<impl Iterator<Item = OwnedUserId> + Clone> {
93 let initial = self.creator(rules)?.into_owned();
94 let additional = self.additional_creators(rules)?;
95
96 Ok(iter::once(initial).chain(additional))
97 }
98
99 pub(super) fn additional_creators(
109 &self,
110 rules: &AuthorizationRules,
111 ) -> Result<impl Iterator<Item = OwnedUserId> + Clone> {
112 #[derive(Deserialize)]
113 struct RoomCreateContentAdditionalCreators {
114 #[serde(default)]
115 additional_creators: Vec<OwnedUserId>,
116 }
117
118 Ok(if rules.additional_room_creators {
119 let content: RoomCreateContentAdditionalCreators =
120 from_raw_json_value(self.content()).map_err(|err: serde_json::Error| {
121 err!("invalid `additional_creators` field in `m.room.create` event: {err}")
122 })?;
123
124 Either::Left(
125 content
126 .additional_creators
127 .into_iter()
128 .sorted()
129 .dedup(),
130 )
131 } else {
132 Either::Right(Vec::new().into_iter())
133 })
134 }
135
136 pub fn has_creator(&self) -> Result<bool> {
138 #[derive(Deserialize)]
139 struct RoomCreateContentCreator {
140 creator: Option<IgnoredAny>,
141 }
142
143 let content: RoomCreateContentCreator =
144 from_raw_json_value(self.content()).map_err(|err: Error| {
145 err!("invalid `creator` field in `m.room.create` event: {err}")
146 })?;
147
148 Ok(content.creator.is_some())
149 }
150}
151
152impl<E: Event> Deref for RoomCreateEvent<E> {
153 type Target = E;
154
155 #[inline]
156 fn deref(&self) -> &Self::Target { &self.0 }
157}