ruma_client_api/room/create_room.rs
1//! `POST /_matrix/client/*/createRoom`
2//!
3//! Create a new room.
4
5pub mod v3 {
6 //! `/v3/` ([spec])
7 //!
8 //! [spec]: https://spec.matrix.org/latest/client-server-api/#post_matrixclientv3createroom
9
10 use assign::assign;
11 use ruma_common::{
12 api::{request, response, Metadata},
13 metadata,
14 room::RoomType,
15 serde::{Raw, StringEnum},
16 OwnedRoomId, OwnedUserId, RoomVersionId,
17 };
18 use ruma_events::{
19 room::{
20 create::{PreviousRoom, RoomCreateEventContent},
21 power_levels::RoomPowerLevelsEventContent,
22 },
23 AnyInitialStateEvent,
24 };
25 use serde::{Deserialize, Serialize};
26
27 use crate::{membership::Invite3pid, room::Visibility, PrivOwnedStr};
28
29 const METADATA: Metadata = metadata! {
30 method: POST,
31 rate_limited: false,
32 authentication: AccessToken,
33 history: {
34 1.0 => "/_matrix/client/r0/createRoom",
35 1.1 => "/_matrix/client/v3/createRoom",
36 }
37 };
38
39 /// Request type for the `create_room` endpoint.
40 #[request(error = crate::Error)]
41 #[derive(Default)]
42 pub struct Request {
43 /// Extra keys to be added to the content of the `m.room.create`.
44 #[serde(default, skip_serializing_if = "Option::is_none")]
45 pub creation_content: Option<Raw<CreationContent>>,
46
47 /// List of state events to send to the new room.
48 ///
49 /// Takes precedence over events set by preset, but gets overridden by name and topic keys.
50 #[serde(default, skip_serializing_if = "<[_]>::is_empty")]
51 pub initial_state: Vec<Raw<AnyInitialStateEvent>>,
52
53 /// A list of user IDs to invite to the room.
54 ///
55 /// This will tell the server to invite everyone in the list to the newly created room.
56 #[serde(default, skip_serializing_if = "<[_]>::is_empty")]
57 pub invite: Vec<OwnedUserId>,
58
59 /// List of third party IDs of users to invite.
60 #[serde(default, skip_serializing_if = "<[_]>::is_empty")]
61 pub invite_3pid: Vec<Invite3pid>,
62
63 /// If set, this sets the `is_direct` flag on room invites.
64 #[serde(default, skip_serializing_if = "ruma_common::serde::is_default")]
65 pub is_direct: bool,
66
67 /// If this is included, an `m.room.name` event will be sent into the room to indicate the
68 /// name of the room.
69 #[serde(skip_serializing_if = "Option::is_none")]
70 pub name: Option<String>,
71
72 /// Power level content to override in the default power level event.
73 #[serde(skip_serializing_if = "Option::is_none")]
74 pub power_level_content_override: Option<Raw<RoomPowerLevelsEventContent>>,
75
76 /// Convenience parameter for setting various default state events based on a preset.
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub preset: Option<RoomPreset>,
79
80 /// The desired room alias local part.
81 #[serde(skip_serializing_if = "Option::is_none")]
82 pub room_alias_name: Option<String>,
83
84 /// Room version to set for the room.
85 ///
86 /// Defaults to homeserver's default if not specified.
87 #[serde(skip_serializing_if = "Option::is_none")]
88 pub room_version: Option<RoomVersionId>,
89
90 /// If this is included, an `m.room.topic` event will be sent into the room to indicate
91 /// the topic for the room.
92 #[serde(skip_serializing_if = "Option::is_none")]
93 pub topic: Option<String>,
94
95 /// A public visibility indicates that the room will be shown in the published room list.
96 ///
97 /// A private visibility will hide the room from the published room list. Defaults to
98 /// `Private`.
99 #[serde(default, skip_serializing_if = "ruma_common::serde::is_default")]
100 pub visibility: Visibility,
101 }
102
103 /// Response type for the `create_room` endpoint.
104 #[response(error = crate::Error)]
105 pub struct Response {
106 /// The created room's ID.
107 pub room_id: OwnedRoomId,
108 }
109
110 impl Request {
111 /// Creates a new `Request` will all-default parameters.
112 pub fn new() -> Self {
113 Default::default()
114 }
115 }
116
117 impl Response {
118 /// Creates a new `Response` with the given room id.
119 pub fn new(room_id: OwnedRoomId) -> Self {
120 Self { room_id }
121 }
122 }
123
124 /// Extra options to be added to the `m.room.create` event.
125 ///
126 /// This is the same as the event content struct for `m.room.create`, but without some fields
127 /// that servers are supposed to ignore.
128 #[derive(Clone, Debug, Deserialize, Serialize)]
129 #[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
130 pub struct CreationContent {
131 /// A list of user IDs to consider as additional creators, and hence grant an "infinite"
132 /// immutable power level, from room version 12 onwards.
133 #[serde(default, skip_serializing_if = "<[_]>::is_empty")]
134 pub additional_creators: Vec<OwnedUserId>,
135
136 /// Whether users on other servers can join this room.
137 ///
138 /// Defaults to `true` if key does not exist.
139 #[serde(
140 rename = "m.federate",
141 default = "ruma_common::serde::default_true",
142 skip_serializing_if = "ruma_common::serde::is_true"
143 )]
144 pub federate: bool,
145
146 /// A reference to the room this room replaces, if the previous room was upgraded.
147 #[serde(skip_serializing_if = "Option::is_none")]
148 pub predecessor: Option<PreviousRoom>,
149
150 /// The room type.
151 ///
152 /// This is currently only used for spaces.
153 #[serde(skip_serializing_if = "Option::is_none", rename = "type")]
154 pub room_type: Option<RoomType>,
155 }
156
157 impl CreationContent {
158 /// Creates a new `CreationContent` with all fields defaulted.
159 pub fn new() -> Self {
160 Self {
161 additional_creators: Vec::new(),
162 federate: true,
163 predecessor: None,
164 room_type: None,
165 }
166 }
167
168 /// Given a `CreationContent` and the other fields that a homeserver has to fill, construct
169 /// a `RoomCreateEventContent`.
170 pub fn into_event_content(
171 self,
172 creator: OwnedUserId,
173 room_version: RoomVersionId,
174 ) -> RoomCreateEventContent {
175 assign!(RoomCreateEventContent::new_v1(creator), {
176 federate: self.federate,
177 room_version: room_version,
178 predecessor: self.predecessor,
179 room_type: self.room_type
180 })
181 }
182
183 /// Returns whether all fields have their default value.
184 pub fn is_empty(&self) -> bool {
185 self.federate && self.predecessor.is_none() && self.room_type.is_none()
186 }
187 }
188
189 impl Default for CreationContent {
190 fn default() -> Self {
191 Self::new()
192 }
193 }
194
195 /// A convenience parameter for setting a few default state events.
196 #[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
197 #[derive(Clone, PartialEq, Eq, StringEnum)]
198 #[ruma_enum(rename_all = "snake_case")]
199 #[non_exhaustive]
200 pub enum RoomPreset {
201 /// `join_rules` is set to `invite` and `history_visibility` is set to `shared`.
202 PrivateChat,
203
204 /// `join_rules` is set to `public` and `history_visibility` is set to `shared`.
205 PublicChat,
206
207 /// Same as `PrivateChat`, but all initial invitees get the same power level as the
208 /// creator.
209 TrustedPrivateChat,
210
211 #[doc(hidden)]
212 _Custom(PrivOwnedStr),
213 }
214}