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