twilight_http/request/guild/
create_guild_channel.rs1use crate::{
2 client::Client,
3 error::Error,
4 request::{self, AuditLogReason, Request, TryIntoRequest},
5 response::{Response, ResponseFuture},
6 routing::Route,
7};
8use serde::Serialize;
9use std::future::IntoFuture;
10use twilight_model::{
11 channel::{
12 forum::{DefaultReaction, ForumLayout, ForumSortOrder, ForumTag},
13 permission_overwrite::PermissionOverwrite,
14 thread::AutoArchiveDuration,
15 Channel, ChannelType, VideoQualityMode,
16 },
17 id::{
18 marker::{ChannelMarker, GuildMarker},
19 Id,
20 },
21};
22use twilight_validate::{
23 channel::{
24 bitrate as validate_bitrate, name as validate_name,
25 rate_limit_per_user as validate_rate_limit_per_user, topic as validate_topic,
26 ChannelValidationError,
27 },
28 request::{audit_reason as validate_audit_reason, ValidationError},
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 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 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 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 fn default_reaction_emoji(mut self, default_reaction_emoji: &'a DefaultReaction) -> Self {
179 if let Ok(fields) = self.fields.as_mut() {
180 fields.default_reaction_emoji = Some(default_reaction_emoji);
181 }
182
183 self
184 }
185
186 pub fn default_sort_order(mut self, default_sort_order: ForumSortOrder) -> Self {
188 if let Ok(fields) = self.fields.as_mut() {
189 fields.default_sort_order = Some(default_sort_order);
190 }
191
192 self
193 }
194
195 pub fn default_thread_rate_limit_per_user(
204 mut self,
205 default_thread_rate_limit_per_user: u16,
206 ) -> Self {
207 self.fields = self.fields.and_then(|mut fields| {
208 validate_rate_limit_per_user(default_thread_rate_limit_per_user)?;
209
210 fields.default_thread_rate_limit_per_user = Some(default_thread_rate_limit_per_user);
211
212 Ok(fields)
213 });
214
215 self
216 }
217
218 pub fn kind(mut self, kind: ChannelType) -> Self {
220 if let Ok(fields) = self.fields.as_mut() {
221 fields.kind = Some(kind);
222 }
223
224 self
225 }
226
227 pub fn nsfw(mut self, nsfw: bool) -> Self {
229 if let Ok(fields) = self.fields.as_mut() {
230 fields.nsfw = Some(nsfw);
231 }
232
233 self
234 }
235
236 pub fn parent_id(mut self, parent_id: Id<ChannelMarker>) -> Self {
239 if let Ok(fields) = self.fields.as_mut() {
240 fields.parent_id = Some(parent_id);
241 }
242
243 self
244 }
245
246 pub fn permission_overwrites(
248 mut self,
249 permission_overwrites: &'a [PermissionOverwrite],
250 ) -> Self {
251 if let Ok(fields) = self.fields.as_mut() {
252 fields.permission_overwrites = Some(permission_overwrites);
253 }
254
255 self
256 }
257
258 pub fn position(mut self, position: u64) -> Self {
263 if let Ok(fields) = self.fields.as_mut() {
264 fields.position = Some(position);
265 }
266
267 self
268 }
269
270 pub fn rate_limit_per_user(mut self, rate_limit_per_user: u16) -> Self {
284 self.fields = self.fields.and_then(|mut fields| {
285 validate_rate_limit_per_user(rate_limit_per_user)?;
286
287 fields.rate_limit_per_user = Some(rate_limit_per_user);
288
289 Ok(fields)
290 });
291
292 self
293 }
294
295 pub fn rtc_region(mut self, rtc_region: &'a str) -> Self {
297 if let Ok(fields) = self.fields.as_mut() {
298 fields.rtc_region = Some(rtc_region);
299 }
300
301 self
302 }
303
304 pub fn topic(mut self, topic: &'a str) -> Self {
317 self.fields = self.fields.and_then(|mut fields| {
318 validate_topic(topic)?;
319
320 fields.topic.replace(topic);
321
322 Ok(fields)
323 });
324
325 self
326 }
327
328 pub fn user_limit(mut self, user_limit: u16) -> Self {
335 if let Ok(fields) = self.fields.as_mut() {
336 fields.user_limit = Some(user_limit);
337 }
338
339 self
340 }
341
342 pub fn video_quality_mode(mut self, video_quality_mode: VideoQualityMode) -> Self {
344 if let Ok(fields) = self.fields.as_mut() {
345 fields.video_quality_mode = Some(video_quality_mode);
346 }
347
348 self
349 }
350}
351
352impl<'a> AuditLogReason<'a> for CreateGuildChannel<'a> {
353 fn reason(mut self, reason: &'a str) -> Self {
354 self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
355
356 self
357 }
358}
359
360impl IntoFuture for CreateGuildChannel<'_> {
361 type Output = Result<Response<Channel>, Error>;
362
363 type IntoFuture = ResponseFuture<Channel>;
364
365 fn into_future(self) -> Self::IntoFuture {
366 let http = self.http;
367
368 match self.try_into_request() {
369 Ok(request) => http.request(request),
370 Err(source) => ResponseFuture::error(source),
371 }
372 }
373}
374
375impl TryIntoRequest for CreateGuildChannel<'_> {
376 fn try_into_request(self) -> Result<Request, Error> {
377 let fields = self.fields.map_err(Error::validation)?;
378 let mut request = Request::builder(&Route::CreateChannel {
379 guild_id: self.guild_id.get(),
380 })
381 .json(&fields);
382
383 if let Some(reason) = self.reason.map_err(Error::validation)? {
384 request = request.headers(request::audit_header(reason)?);
385 }
386
387 request.build()
388 }
389}