twilight_http/request/guild/
create_guild_channel.rs1#[cfg(not(target_os = "wasi"))]
2use crate::response::{Response, ResponseFuture};
3use crate::{
4 client::Client,
5 error::Error,
6 request::{self, AuditLogReason, Request, TryIntoRequest},
7 routing::Route,
8};
9use serde::Serialize;
10use std::future::IntoFuture;
11use twilight_model::{
12 channel::{
13 Channel, ChannelType, VideoQualityMode,
14 forum::{DefaultReaction, ForumLayout, ForumSortOrder, ForumTag},
15 permission_overwrite::PermissionOverwrite,
16 thread::AutoArchiveDuration,
17 },
18 id::{
19 Id,
20 marker::{ChannelMarker, GuildMarker},
21 },
22};
23use twilight_validate::{
24 channel::{
25 ChannelValidationError, bitrate as validate_bitrate, name as validate_name,
26 rate_limit_per_user as validate_rate_limit_per_user, topic as validate_topic,
27 },
28 request::{ValidationError, audit_reason as validate_audit_reason},
29};
30
31#[derive(Serialize)]
32struct CreateGuildChannelFields<'a> {
33 #[serde(skip_serializing_if = "Option::is_none")]
34 available_tags: Option<&'a [ForumTag]>,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 bitrate: Option<u32>,
37 #[serde(skip_serializing_if = "Option::is_none")]
38 default_auto_archive_duration: Option<AutoArchiveDuration>,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 default_forum_layout: Option<ForumLayout>,
41 #[serde(skip_serializing_if = "Option::is_none")]
42 default_reaction_emoji: Option<&'a DefaultReaction>,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 default_sort_order: Option<ForumSortOrder>,
45 #[serde(skip_serializing_if = "Option::is_none")]
50 default_thread_rate_limit_per_user: Option<u16>,
51 #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
52 kind: Option<ChannelType>,
53 name: &'a str,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 nsfw: Option<bool>,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 parent_id: Option<Id<ChannelMarker>>,
58 #[serde(skip_serializing_if = "Option::is_none")]
59 permission_overwrites: Option<&'a [PermissionOverwrite]>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 position: Option<u64>,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 rate_limit_per_user: Option<u16>,
64 #[serde(skip_serializing_if = "Option::is_none")]
65 rtc_region: Option<&'a str>,
66 #[serde(skip_serializing_if = "Option::is_none")]
67 topic: Option<&'a str>,
68 #[serde(skip_serializing_if = "Option::is_none")]
69 user_limit: Option<u16>,
70 #[serde(skip_serializing_if = "Option::is_none")]
71 video_quality_mode: Option<VideoQualityMode>,
72}
73
74#[must_use = "requests must be configured and executed"]
79pub struct CreateGuildChannel<'a> {
80 fields: Result<CreateGuildChannelFields<'a>, ChannelValidationError>,
81 guild_id: Id<GuildMarker>,
82 http: &'a Client,
83 reason: Result<Option<&'a str>, ValidationError>,
84}
85
86impl<'a> CreateGuildChannel<'a> {
87 pub(crate) fn new(http: &'a Client, guild_id: Id<GuildMarker>, name: &'a str) -> Self {
88 let fields = Ok(CreateGuildChannelFields {
89 available_tags: None,
90 bitrate: None,
91 default_auto_archive_duration: None,
92 default_forum_layout: None,
93 default_reaction_emoji: None,
94 default_sort_order: None,
95 default_thread_rate_limit_per_user: None,
96 kind: None,
97 name,
98 nsfw: None,
99 parent_id: None,
100 permission_overwrites: None,
101 position: None,
102 rate_limit_per_user: None,
103 rtc_region: None,
104 topic: None,
105 user_limit: None,
106 video_quality_mode: None,
107 })
108 .and_then(|fields| {
109 validate_name(name)?;
110
111 Ok(fields)
112 });
113
114 Self {
115 fields,
116 guild_id,
117 http,
118 reason: Ok(None),
119 }
120 }
121
122 pub const fn available_tags(mut self, available_tags: &'a [ForumTag]) -> Self {
124 if let Ok(fields) = self.fields.as_mut() {
125 fields.available_tags = Some(available_tags);
126 }
127
128 self
129 }
130
131 pub fn bitrate(mut self, bitrate: u32) -> Self {
141 self.fields = self.fields.and_then(|mut fields| {
142 validate_bitrate(bitrate)?;
143
144 fields.bitrate = Some(bitrate);
145
146 Ok(fields)
147 });
148
149 self
150 }
151
152 pub const fn default_auto_archive_duration(
158 mut self,
159 auto_archive_duration: AutoArchiveDuration,
160 ) -> Self {
161 if let Ok(fields) = self.fields.as_mut() {
162 fields.default_auto_archive_duration = Some(auto_archive_duration);
163 }
164
165 self
166 }
167
168 pub const fn default_forum_layout(mut self, default_forum_layout: ForumLayout) -> Self {
170 if let Ok(fields) = self.fields.as_mut() {
171 fields.default_forum_layout = Some(default_forum_layout);
172 }
173
174 self
175 }
176
177 pub const fn default_reaction_emoji(
179 mut self,
180 default_reaction_emoji: &'a DefaultReaction,
181 ) -> Self {
182 if let Ok(fields) = self.fields.as_mut() {
183 fields.default_reaction_emoji = Some(default_reaction_emoji);
184 }
185
186 self
187 }
188
189 pub const fn default_sort_order(mut self, default_sort_order: ForumSortOrder) -> Self {
191 if let Ok(fields) = self.fields.as_mut() {
192 fields.default_sort_order = Some(default_sort_order);
193 }
194
195 self
196 }
197
198 pub fn default_thread_rate_limit_per_user(
207 mut self,
208 default_thread_rate_limit_per_user: u16,
209 ) -> Self {
210 self.fields = self.fields.and_then(|mut fields| {
211 validate_rate_limit_per_user(default_thread_rate_limit_per_user)?;
212
213 fields.default_thread_rate_limit_per_user = Some(default_thread_rate_limit_per_user);
214
215 Ok(fields)
216 });
217
218 self
219 }
220
221 pub const fn kind(mut self, kind: ChannelType) -> Self {
223 if let Ok(fields) = self.fields.as_mut() {
224 fields.kind = Some(kind);
225 }
226
227 self
228 }
229
230 pub const fn nsfw(mut self, nsfw: bool) -> Self {
232 if let Ok(fields) = self.fields.as_mut() {
233 fields.nsfw = Some(nsfw);
234 }
235
236 self
237 }
238
239 pub const fn parent_id(mut self, parent_id: Id<ChannelMarker>) -> Self {
242 if let Ok(fields) = self.fields.as_mut() {
243 fields.parent_id = Some(parent_id);
244 }
245
246 self
247 }
248
249 pub const fn permission_overwrites(
251 mut self,
252 permission_overwrites: &'a [PermissionOverwrite],
253 ) -> Self {
254 if let Ok(fields) = self.fields.as_mut() {
255 fields.permission_overwrites = Some(permission_overwrites);
256 }
257
258 self
259 }
260
261 pub const fn position(mut self, position: u64) -> Self {
266 if let Ok(fields) = self.fields.as_mut() {
267 fields.position = Some(position);
268 }
269
270 self
271 }
272
273 pub fn rate_limit_per_user(mut self, rate_limit_per_user: u16) -> Self {
287 self.fields = self.fields.and_then(|mut fields| {
288 validate_rate_limit_per_user(rate_limit_per_user)?;
289
290 fields.rate_limit_per_user = Some(rate_limit_per_user);
291
292 Ok(fields)
293 });
294
295 self
296 }
297
298 pub const fn rtc_region(mut self, rtc_region: &'a str) -> Self {
300 if let Ok(fields) = self.fields.as_mut() {
301 fields.rtc_region = Some(rtc_region);
302 }
303
304 self
305 }
306
307 pub fn topic(mut self, topic: &'a str) -> Self {
320 self.fields = self.fields.and_then(|mut fields| {
321 validate_topic(topic)?;
322
323 fields.topic.replace(topic);
324
325 Ok(fields)
326 });
327
328 self
329 }
330
331 pub const fn user_limit(mut self, user_limit: u16) -> Self {
338 if let Ok(fields) = self.fields.as_mut() {
339 fields.user_limit = Some(user_limit);
340 }
341
342 self
343 }
344
345 pub const fn video_quality_mode(mut self, video_quality_mode: VideoQualityMode) -> Self {
347 if let Ok(fields) = self.fields.as_mut() {
348 fields.video_quality_mode = Some(video_quality_mode);
349 }
350
351 self
352 }
353}
354
355impl<'a> AuditLogReason<'a> for CreateGuildChannel<'a> {
356 fn reason(mut self, reason: &'a str) -> Self {
357 self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
358
359 self
360 }
361}
362
363#[cfg(not(target_os = "wasi"))]
364impl IntoFuture for CreateGuildChannel<'_> {
365 type Output = Result<Response<Channel>, Error>;
366
367 type IntoFuture = ResponseFuture<Channel>;
368
369 fn into_future(self) -> Self::IntoFuture {
370 let http = self.http;
371
372 match self.try_into_request() {
373 Ok(request) => http.request(request),
374 Err(source) => ResponseFuture::error(source),
375 }
376 }
377}
378
379impl TryIntoRequest for CreateGuildChannel<'_> {
380 fn try_into_request(self) -> Result<Request, Error> {
381 let fields = self.fields.map_err(Error::validation)?;
382 let mut request = Request::builder(&Route::CreateChannel {
383 guild_id: self.guild_id.get(),
384 })
385 .json(&fields);
386
387 if let Some(reason) = self.reason.map_err(Error::validation)? {
388 request = request.headers(request::audit_header(reason)?);
389 }
390
391 request.build()
392 }
393}