twilight_http/request/channel/thread/create_forum_thread/
mod.rs1mod message;
2
3pub use self::message::CreateForumThreadMessage;
4
5use self::message::CreateForumThreadMessageFields;
6use crate::{
7 client::Client,
8 error::Error,
9 request::{self, AuditLogReason, Nullable, Request, attachment::AttachmentManager},
10 response::ResponseFuture,
11 routing::Route,
12};
13use serde::{Deserialize, Serialize};
14use twilight_model::{
15 channel::{Channel, Message, thread::AutoArchiveDuration},
16 id::{
17 Id,
18 marker::{ChannelMarker, TagMarker},
19 },
20};
21use twilight_validate::request::{ValidationError, audit_reason as validate_audit_reason};
22
23#[derive(Deserialize, Serialize)]
24pub struct ForumThread {
25 #[serde(flatten)]
26 pub channel: Channel,
27 pub message: Message,
28}
29
30#[derive(Serialize)]
31struct CreateForumThreadFields<'a> {
32 #[serde(skip_serializing_if = "Option::is_none")]
33 applied_tags: Option<&'a [Id<TagMarker>]>,
34 #[serde(skip_serializing_if = "Option::is_none")]
35 auto_archive_duration: Option<AutoArchiveDuration>,
36 message: CreateForumThreadMessageFields<'a>,
37 name: &'a str,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 rate_limit_per_user: Option<u16>,
40}
41
42#[must_use = "requests must be configured and executed"]
48pub struct CreateForumThread<'a> {
49 attachment_manager: AttachmentManager<'a>,
50 channel_id: Id<ChannelMarker>,
51 fields: CreateForumThreadFields<'a>,
52 http: &'a Client,
53 reason: Result<Option<&'a str>, ValidationError>,
54}
55
56impl<'a> CreateForumThread<'a> {
57 pub(crate) const fn new(
58 http: &'a Client,
59 channel_id: Id<ChannelMarker>,
60 name: &'a str,
61 ) -> Self {
62 Self {
63 attachment_manager: AttachmentManager::new(),
64 channel_id,
65 fields: CreateForumThreadFields {
66 applied_tags: None,
67 auto_archive_duration: None,
68 message: CreateForumThreadMessageFields {
69 allowed_mentions: None,
70 attachments: None,
71 components: None,
72 content: None,
73 embeds: None,
74 flags: None,
75 payload_json: None,
76 sticker_ids: None,
77 },
78 name,
79 rate_limit_per_user: None,
80 },
81 http,
82 reason: Ok(None),
83 }
84 }
85
86 pub const fn applied_tags(mut self, applied_tags: &'a [Id<TagMarker>]) -> Self {
88 self.fields.applied_tags = Some(applied_tags);
89
90 self
91 }
92
93 pub const fn auto_archive_duration(
99 mut self,
100 auto_archive_duration: AutoArchiveDuration,
101 ) -> Self {
102 self.fields.auto_archive_duration = Some(auto_archive_duration);
103
104 self
105 }
106
107 pub const fn message(self) -> CreateForumThreadMessage<'a> {
108 CreateForumThreadMessage::new(self)
109 }
110
111 fn exec(self) -> ResponseFuture<ForumThread> {
115 let http = self.http;
116
117 match self.try_into_request() {
118 Ok(request) => http.request(request),
119 Err(source) => ResponseFuture::error(source),
120 }
121 }
122
123 fn try_into_request(mut self) -> Result<Request, Error> {
124 let mut request = Request::builder(&Route::CreateForumThread {
125 channel_id: self.channel_id.get(),
126 });
127
128 if let Some(reason) = self.reason.map_err(Error::validation)? {
129 request = request.headers(request::audit_header(reason)?);
130 }
131
132 if self.fields.message.allowed_mentions.is_none()
134 && let Some(allowed_mentions) = self.http.default_allowed_mentions()
135 {
136 self.fields.message.allowed_mentions = Some(Nullable(Some(allowed_mentions)));
137 }
138
139 if !self.attachment_manager.is_empty() {
142 let form = if let Some(payload_json) = self.fields.message.payload_json {
143 self.attachment_manager.build_form(payload_json)
144 } else {
145 self.fields.message.attachments =
146 Some(self.attachment_manager.get_partial_attachments());
147
148 let fields = crate::json::to_vec(&self.fields).map_err(Error::json)?;
149
150 self.attachment_manager.build_form(fields.as_ref())
151 };
152
153 request = request.form(form);
154 } else if let Some(payload_json) = self.fields.message.payload_json {
155 request = request.body(payload_json.to_vec());
156 } else {
157 request = request.json(&self.fields);
158 }
159
160 request.build()
161 }
162}
163
164impl<'a> AuditLogReason<'a> for CreateForumThread<'a> {
165 fn reason(mut self, reason: &'a str) -> Self {
166 self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
167
168 self
169 }
170}