twilight_http/request/channel/
update_channel.rs1use crate::{
2 client::Client,
3 error::Error,
4 request::{self, AuditLogReason, Nullable, 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 Channel, ChannelFlags, ChannelType, VideoQualityMode,
15 },
16 id::{marker::ChannelMarker, Id},
17};
18use twilight_validate::{
19 channel::{
20 bitrate as validate_bitrate, forum_topic as validate_forum_topic, name as validate_name,
21 topic as validate_topic, user_limit as validate_user_limit, ChannelValidationError,
22 },
23 request::{audit_reason as validate_audit_reason, ValidationError},
24};
25
26#[derive(Serialize)]
29struct UpdateChannelFields<'a> {
30 #[serde(skip_serializing_if = "Option::is_none")]
31 available_tags: Option<&'a [ForumTag]>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 bitrate: Option<u32>,
34 #[serde(skip_serializing_if = "Option::is_none")]
35 default_forum_layout: Option<ForumLayout>,
36 #[serde(skip_serializing_if = "Option::is_none")]
37 default_reaction_emoji: Option<Nullable<&'a DefaultReaction>>,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 default_sort_order: Option<Nullable<ForumSortOrder>>,
40 #[serde(skip_serializing_if = "Option::is_none")]
41 default_thread_rate_limit_per_user: Option<Nullable<u16>>,
42 #[serde(skip_serializing_if = "Option::is_none")]
43 flags: Option<ChannelFlags>,
44 #[serde(rename = "type")]
45 #[serde(skip_serializing_if = "Option::is_none")]
46 kind: Option<ChannelType>,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 name: Option<&'a str>,
49 #[serde(skip_serializing_if = "Option::is_none")]
50 nsfw: Option<bool>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 parent_id: Option<Nullable<Id<ChannelMarker>>>,
53 #[serde(skip_serializing_if = "Option::is_none")]
54 permission_overwrites: Option<&'a [PermissionOverwrite]>,
55 #[serde(skip_serializing_if = "Option::is_none")]
56 position: Option<u64>,
57 #[serde(skip_serializing_if = "Option::is_none")]
58 rate_limit_per_user: Option<u16>,
59 #[serde(skip_serializing_if = "Option::is_none")]
60 rtc_region: Option<Nullable<&'a str>>,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 topic: Option<&'a str>,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 user_limit: Option<u16>,
65 #[serde(skip_serializing_if = "Option::is_none")]
66 video_quality_mode: Option<VideoQualityMode>,
67}
68
69#[must_use = "requests must be configured and executed"]
74pub struct UpdateChannel<'a> {
75 channel_id: Id<ChannelMarker>,
76 fields: Result<UpdateChannelFields<'a>, ChannelValidationError>,
77 http: &'a Client,
78 reason: Result<Option<&'a str>, ValidationError>,
79}
80
81impl<'a> UpdateChannel<'a> {
82 pub(crate) const fn new(http: &'a Client, channel_id: Id<ChannelMarker>) -> Self {
83 Self {
84 channel_id,
85 fields: Ok(UpdateChannelFields {
86 available_tags: None,
87 bitrate: None,
88 default_forum_layout: None,
89 default_reaction_emoji: None,
90 default_sort_order: None,
91 default_thread_rate_limit_per_user: None,
92 flags: None,
93 kind: None,
94 name: None,
95 nsfw: None,
96 parent_id: None,
97 permission_overwrites: None,
98 position: None,
99 rate_limit_per_user: None,
100 rtc_region: None,
101 topic: None,
102 user_limit: None,
103 video_quality_mode: None,
104 }),
105 http,
106 reason: Ok(None),
107 }
108 }
109
110 pub fn available_tags(mut self, available_tags: &'a [ForumTag]) -> Self {
112 if let Ok(fields) = self.fields.as_mut() {
113 fields.available_tags = Some(available_tags);
114 }
115
116 self
117 }
118
119 pub fn bitrate(mut self, bitrate: u32) -> Self {
129 self.fields = self.fields.and_then(|mut fields| {
130 validate_bitrate(bitrate)?;
131 fields.bitrate = Some(bitrate);
132
133 Ok(fields)
134 });
135
136 self
137 }
138
139 pub fn default_forum_layout(mut self, default_forum_layout: ForumLayout) -> Self {
141 if let Ok(fields) = self.fields.as_mut() {
142 fields.default_forum_layout = Some(default_forum_layout);
143 }
144
145 self
146 }
147
148 pub fn default_reaction_emoji(
150 mut self,
151 default_reaction_emoji: Option<&'a DefaultReaction>,
152 ) -> Self {
153 if let Ok(fields) = self.fields.as_mut() {
154 fields.default_reaction_emoji = Some(Nullable(default_reaction_emoji));
155 }
156
157 self
158 }
159
160 pub fn default_sort_order(mut self, default_sort_order: Option<ForumSortOrder>) -> Self {
162 if let Ok(fields) = self.fields.as_mut() {
163 fields.default_sort_order = Some(Nullable(default_sort_order));
164 }
165
166 self
167 }
168
169 pub fn default_thread_rate_limit_per_user(
183 mut self,
184 default_thread_rate_limit_per_user: Option<u16>,
185 ) -> Self {
186 self.fields = self.fields.and_then(|mut fields| {
187 if let Some(default_thread_rate_limit_per_user) = default_thread_rate_limit_per_user {
188 twilight_validate::channel::rate_limit_per_user(
189 default_thread_rate_limit_per_user,
190 )?;
191 }
192
193 fields.default_thread_rate_limit_per_user =
194 Some(Nullable(default_thread_rate_limit_per_user));
195
196 Ok(fields)
197 });
198
199 self
200 }
201
202 pub fn flags(mut self, flags: ChannelFlags) -> Self {
204 if let Ok(fields) = self.fields.as_mut() {
205 fields.flags = Some(flags);
206 }
207
208 self
209 }
210
211 pub fn forum_topic(mut self, topic: Option<&'a str>) -> Self {
225 self.fields = self.fields.and_then(|mut fields| {
226 if let Some(topic) = topic {
227 validate_forum_topic(topic)?;
228 }
229
230 fields.topic = topic;
231
232 Ok(fields)
233 });
234
235 self
236 }
237
238 pub fn name(mut self, name: &'a str) -> Self {
249 self.fields = self.fields.and_then(|mut fields| {
250 validate_name(name)?;
251 fields.name = Some(name);
252
253 Ok(fields)
254 });
255
256 self
257 }
258
259 pub fn nsfw(mut self, nsfw: bool) -> Self {
261 if let Ok(fields) = self.fields.as_mut() {
262 fields.nsfw = Some(nsfw);
263 }
264
265 self
266 }
267
268 pub fn parent_id(mut self, parent_id: Option<Id<ChannelMarker>>) -> Self {
271 if let Ok(fields) = self.fields.as_mut() {
272 fields.parent_id = Some(Nullable(parent_id));
273 }
274
275 self
276 }
277
278 pub fn permission_overwrites(
281 mut self,
282 permission_overwrites: &'a [PermissionOverwrite],
283 ) -> Self {
284 if let Ok(fields) = self.fields.as_mut() {
285 fields.permission_overwrites = Some(permission_overwrites);
286 }
287
288 self
289 }
290
291 pub fn position(mut self, position: u64) -> Self {
296 if let Ok(fields) = self.fields.as_mut() {
297 fields.position = Some(position);
298 }
299
300 self
301 }
302
303 pub fn rate_limit_per_user(mut self, rate_limit_per_user: u16) -> Self {
317 self.fields = self.fields.and_then(|mut fields| {
318 twilight_validate::channel::rate_limit_per_user(rate_limit_per_user)?;
319 fields.rate_limit_per_user = Some(rate_limit_per_user);
320
321 Ok(fields)
322 });
323
324 self
325 }
326
327 pub fn rtc_region(mut self, rtc_region: Option<&'a str>) -> Self {
331 if let Ok(fields) = self.fields.as_mut() {
332 fields.rtc_region = Some(Nullable(rtc_region));
333 }
334
335 self
336 }
337
338 pub fn topic(mut self, topic: &'a str) -> Self {
350 self.fields = self.fields.and_then(|mut fields| {
351 validate_topic(topic)?;
352 fields.topic.replace(topic);
353
354 Ok(fields)
355 });
356
357 self
358 }
359
360 pub fn user_limit(mut self, user_limit: u16) -> Self {
372 self.fields = self.fields.and_then(|mut fields| {
373 validate_user_limit(user_limit)?;
374 fields.user_limit = Some(user_limit);
375
376 Ok(fields)
377 });
378
379 self
380 }
381
382 pub fn video_quality_mode(mut self, video_quality_mode: VideoQualityMode) -> Self {
384 if let Ok(fields) = self.fields.as_mut() {
385 fields.video_quality_mode = Some(video_quality_mode);
386 }
387
388 self
389 }
390
391 pub fn kind(mut self, kind: ChannelType) -> Self {
399 if let Ok(fields) = self.fields.as_mut() {
400 fields.kind = Some(kind);
401 }
402
403 self
404 }
405}
406
407impl<'a> AuditLogReason<'a> for UpdateChannel<'a> {
408 fn reason(mut self, reason: &'a str) -> Self {
409 self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
410
411 self
412 }
413}
414
415impl IntoFuture for UpdateChannel<'_> {
416 type Output = Result<Response<Channel>, Error>;
417
418 type IntoFuture = ResponseFuture<Channel>;
419
420 fn into_future(self) -> Self::IntoFuture {
421 let http = self.http;
422
423 match self.try_into_request() {
424 Ok(request) => http.request(request),
425 Err(source) => ResponseFuture::error(source),
426 }
427 }
428}
429
430impl TryIntoRequest for UpdateChannel<'_> {
431 fn try_into_request(self) -> Result<Request, Error> {
432 let fields = self.fields.map_err(Error::validation)?;
433 let mut request = Request::builder(&Route::UpdateChannel {
434 channel_id: self.channel_id.get(),
435 })
436 .json(&fields);
437
438 if let Some(reason) = self.reason.map_err(Error::validation)? {
439 request = request.headers(request::audit_header(reason)?);
440 }
441
442 request.build()
443 }
444}