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::{thread::AutoArchiveDuration, Channel, ChannelType},
12 id::{marker::ChannelMarker, Id},
13};
14use twilight_validate::channel::{
15 is_thread as validate_is_thread, name as validate_name, ChannelValidationError,
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 fn auto_archive_duration(mut self, auto_archive_duration: AutoArchiveDuration) -> Self {
74 if let Ok(fields) = self.fields.as_mut() {
75 fields.auto_archive_duration = Some(auto_archive_duration);
76 }
77
78 self
79 }
80
81 pub fn invitable(mut self, invitable: bool) -> Self {
83 if let Ok(fields) = self.fields.as_mut() {
84 fields.invitable = Some(invitable);
85 }
86
87 self
88 }
89}
90
91impl IntoFuture for CreateThread<'_> {
92 type Output = Result<Response<Channel>, Error>;
93
94 type IntoFuture = ResponseFuture<Channel>;
95
96 fn into_future(self) -> Self::IntoFuture {
97 let http = self.http;
98
99 match self.try_into_request() {
100 Ok(request) => http.request(request),
101 Err(source) => ResponseFuture::error(source),
102 }
103 }
104}
105
106impl TryIntoRequest for CreateThread<'_> {
107 fn try_into_request(self) -> Result<Request, Error> {
108 let fields = self.fields.map_err(Error::validation)?;
109
110 Request::builder(&Route::CreateThread {
111 channel_id: self.channel_id.get(),
112 })
113 .json(&fields)
114 .build()
115 }
116}