twilight_http/request/channel/thread/create_forum_thread/
message.rs1use super::{CreateForumThread, ForumThread};
2use crate::{
3 request::{attachment::PartialAttachment, Nullable, TryIntoRequest},
4 response::{Response, ResponseFuture},
5 Error,
6};
7use serde::Serialize;
8use std::{future::IntoFuture, mem};
9use twilight_model::{
10 channel::message::{AllowedMentions, Component, Embed, MessageFlags},
11 http::attachment::Attachment,
12 id::{marker::StickerMarker, Id},
13};
14use twilight_validate::message::{
15 attachment_filename as validate_attachment_filename, components as validate_components,
16 content as validate_content, embeds as validate_embeds, sticker_ids as validate_sticker_ids,
17 MessageValidationError,
18};
19
20#[derive(Serialize)]
22pub(super) struct CreateForumThreadMessageFields<'a> {
23 #[serde(skip_serializing_if = "Option::is_none")]
24 pub(super) allowed_mentions: Option<Nullable<&'a AllowedMentions>>,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub(super) attachments: Option<Vec<PartialAttachment<'a>>>,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 pub(super) components: Option<&'a [Component]>,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub(super) content: Option<&'a str>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 pub(super) embeds: Option<&'a [Embed]>,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub(super) flags: Option<MessageFlags>,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 pub(super) payload_json: Option<&'a [u8]>,
37 #[serde(skip_serializing_if = "Option::is_none")]
38 pub(super) sticker_ids: Option<&'a [Id<StickerMarker>]>,
39}
40
41#[must_use = "requests must be configured and executed"]
42pub struct CreateForumThreadMessage<'a>(Result<CreateForumThread<'a>, MessageValidationError>);
43
44impl<'a> CreateForumThreadMessage<'a> {
45 pub(super) const fn new(inner: CreateForumThread<'a>) -> Self {
46 Self(Ok(inner))
47 }
48
49 pub fn allowed_mentions(mut self, allowed_mentions: Option<&'a AllowedMentions>) -> Self {
54 if let Ok(inner) = self.0.as_mut() {
55 inner.fields.message.allowed_mentions = Some(Nullable(allowed_mentions));
56 }
57
58 self
59 }
60
61 pub fn attachments(mut self, attachments: &'a [Attachment]) -> Self {
72 if self.0.is_ok() {
73 let validation = attachments
74 .iter()
75 .try_for_each(|attachment| validate_attachment_filename(&attachment.filename));
76
77 if let Err(source) = validation {
78 self.0 = Err(source);
79 } else if let Ok(inner) = self.0.as_mut() {
80 let mut manager = mem::take(&mut inner.attachment_manager);
81 manager = manager.set_files(attachments.iter().collect());
82
83 inner.attachment_manager = manager;
84 }
85 }
86
87 self
88 }
89
90 pub fn components(mut self, components: &'a [Component]) -> Self {
102 self.0 = self.0.and_then(|mut inner| {
103 validate_components(
104 components,
105 inner
106 .fields
107 .message
108 .flags
109 .is_some_and(|f| f.contains(MessageFlags::IS_COMPONENTS_V2)),
110 )?;
111 inner.fields.message.components = Some(components);
112
113 Ok(inner)
114 });
115
116 self
117 }
118
119 pub fn content(mut self, content: &'a str) -> Self {
130 self.0 = self.0.and_then(|mut inner| {
131 validate_content(content)?;
132 inner.fields.message.content = Some(content);
133
134 Ok(inner)
135 });
136
137 self
138 }
139
140 pub fn embeds(mut self, embeds: &'a [Embed]) -> Self {
161 self.0 = self.0.and_then(|mut inner| {
162 validate_embeds(embeds)?;
163 inner.fields.message.embeds = Some(embeds);
164
165 Ok(inner)
166 });
167
168 self
169 }
170
171 pub fn flags(mut self, flags: MessageFlags) -> Self {
179 if let Ok(inner) = self.0.as_mut() {
180 inner.fields.message.flags = Some(flags);
181 }
182
183 self
184 }
185
186 pub fn payload_json(mut self, payload_json: &'a [u8]) -> Self {
199 if let Ok(inner) = self.0.as_mut() {
200 inner.fields.message.payload_json = Some(payload_json);
201 }
202
203 self
204 }
205
206 pub fn sticker_ids(mut self, sticker_ids: &'a [Id<StickerMarker>]) -> Self {
214 self.0 = self.0.and_then(|mut inner| {
215 validate_sticker_ids(sticker_ids)?;
216 inner.fields.message.sticker_ids = Some(sticker_ids);
217
218 Ok(inner)
219 });
220
221 self
222 }
223}
224
225impl IntoFuture for CreateForumThreadMessage<'_> {
226 type Output = Result<Response<ForumThread>, Error>;
227
228 type IntoFuture = ResponseFuture<ForumThread>;
229
230 fn into_future(self) -> Self::IntoFuture {
231 match self.0 {
232 Ok(inner) => inner.exec(),
233 Err(source) => ResponseFuture::error(Error::validation(source)),
234 }
235 }
236}
237
238impl TryIntoRequest for CreateForumThreadMessage<'_> {
239 fn try_into_request(self) -> Result<crate::request::Request, Error> {
240 self.0
241 .map_err(Error::validation)
242 .and_then(CreateForumThread::try_into_request)
243 }
244}