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