twilight_http/request/channel/thread/
create_thread.rs1use crate::{
2 client::Client,
3 error::Error,
4 request::{Request, TryIntoRequest},
5 response::{Response, ResponseFuture},
6 routing::Route,
7};
8use serde::Serialize;
9use std::future::IntoFuture;
10use twilight_model::{
11 channel::{Channel, ChannelType, thread::AutoArchiveDuration},
12 id::{Id, marker::ChannelMarker},
13};
14use twilight_validate::channel::{
15 ChannelValidationError, is_thread as validate_is_thread, name as validate_name,
16};
17
18#[derive(Serialize)]
19struct CreateThreadFields<'a> {
20 #[serde(skip_serializing_if = "Option::is_none")]
21 auto_archive_duration: Option<AutoArchiveDuration>,
22 #[serde(skip_serializing_if = "Option::is_none")]
23 invitable: Option<bool>,
24 #[serde(rename = "type")]
25 kind: ChannelType,
26 name: &'a str,
27}
28
29#[must_use = "requests must be configured and executed"]
36pub struct CreateThread<'a> {
37 channel_id: Id<ChannelMarker>,
38 fields: Result<CreateThreadFields<'a>, ChannelValidationError>,
39 http: &'a Client,
40}
41
42impl<'a> CreateThread<'a> {
43 pub(crate) fn new(
44 http: &'a Client,
45 channel_id: Id<ChannelMarker>,
46 name: &'a str,
47 kind: ChannelType,
48 ) -> Self {
49 let fields = Ok(CreateThreadFields {
50 auto_archive_duration: None,
51 invitable: None,
52 kind,
53 name,
54 })
55 .and_then(|fields| {
56 validate_name(name)?;
57 validate_is_thread(kind)?;
58
59 Ok(fields)
60 });
61
62 Self {
63 channel_id,
64 fields,
65 http,
66 }
67 }
68
69 pub const fn auto_archive_duration(
74 mut self,
75 auto_archive_duration: AutoArchiveDuration,
76 ) -> Self {
77 if let Ok(fields) = self.fields.as_mut() {
78 fields.auto_archive_duration = Some(auto_archive_duration);
79 }
80
81 self
82 }
83
84 pub const fn invitable(mut self, invitable: bool) -> Self {
86 if let Ok(fields) = self.fields.as_mut() {
87 fields.invitable = Some(invitable);
88 }
89
90 self
91 }
92}
93
94impl IntoFuture for CreateThread<'_> {
95 type Output = Result<Response<Channel>, Error>;
96
97 type IntoFuture = ResponseFuture<Channel>;
98
99 fn into_future(self) -> Self::IntoFuture {
100 let http = self.http;
101
102 match self.try_into_request() {
103 Ok(request) => http.request(request),
104 Err(source) => ResponseFuture::error(source),
105 }
106 }
107}
108
109impl TryIntoRequest for CreateThread<'_> {
110 fn try_into_request(self) -> Result<Request, Error> {
111 let fields = self.fields.map_err(Error::validation)?;
112
113 Request::builder(&Route::CreateThread {
114 channel_id: self.channel_id.get(),
115 })
116 .json(&fields)
117 .build()
118 }
119}