Skip to main content

twilight_util/builder/
interaction_response.rs

1//! Create [`InteractionResponse`]s with builders.
2//!
3//! # Example
4//!
5//! ```
6//! use twilight_util::builder::interaction_response::ChannelMessageBuilder;
7//!
8//! ChannelMessageBuilder::new().content("Congrats on sending your command!");
9//! ```
10
11use twilight_model::{
12    application::command::CommandOptionChoice,
13    channel::message::{AllowedMentions, Component, Embed, MessageFlags},
14    http::{
15        attachment::Attachment,
16        interaction::{InteractionResponse, InteractionResponseData, InteractionResponseType},
17    },
18    poll::Poll,
19};
20
21/// Builder for a [`InteractionResponse`] of type [`InteractionResponseType::ApplicationCommandAutocompleteResult`].
22#[derive(Clone, Debug)]
23#[must_use = "builders have no effect if unused"]
24pub struct AutocompleteBuilder(InteractionResponseData);
25
26impl AutocompleteBuilder {
27    /// Creates a new default builder.
28    pub fn new(choices: impl IntoIterator<Item = CommandOptionChoice>) -> Self {
29        Self(InteractionResponseData {
30            choices: Some(FromIterator::from_iter(choices)),
31            ..Default::default()
32        })
33    }
34
35    /// Builds the [`InteractionResponse`].
36    pub fn build(self) -> InteractionResponse {
37        InteractionResponse {
38            kind: InteractionResponseType::ApplicationCommandAutocompleteResult,
39            data: Some(self.0),
40        }
41    }
42}
43
44impl From<AutocompleteBuilder> for InteractionResponse {
45    fn from(builder: AutocompleteBuilder) -> Self {
46        builder.build()
47    }
48}
49
50/// Builder for a [`InteractionResponse`] of type [`InteractionResponseType::ChannelMessageWithSource`].
51#[derive(Clone, Debug, Default)]
52#[must_use = "builders have no effect if unused"]
53pub struct ChannelMessageBuilder(InteractionResponseData);
54
55impl ChannelMessageBuilder {
56    /// Creates a new default builder.
57    pub fn new() -> Self {
58        Self(InteractionResponseData::default())
59    }
60
61    /// Builds the [`InteractionResponse`].
62    pub fn build(self) -> InteractionResponse {
63        InteractionResponse {
64            kind: InteractionResponseType::ChannelMessageWithSource,
65            data: Some(self.0),
66        }
67    }
68
69    /// Sets the allowed mentions filter.
70    ///
71    /// Defaults to no filter.
72    pub fn allowed_mentions(mut self, allowed_mentions: AllowedMentions) -> Self {
73        self.0.allowed_mentions = Some(allowed_mentions);
74
75        self
76    }
77
78    /// Sets the attachments.
79    ///
80    /// Defaults to no attachments.
81    pub fn attachments(mut self, attachments: impl IntoIterator<Item = Attachment>) -> Self {
82        self.0.attachments = Some(FromIterator::from_iter(attachments));
83
84        self
85    }
86
87    /// Sets the components.
88    ///
89    /// Defaults to no components.
90    pub fn components(
91        mut self,
92        components: impl IntoIterator<Item = impl Into<Component>>,
93    ) -> Self {
94        self.0.components = Some(components.into_iter().map(Into::into).collect());
95
96        self
97    }
98
99    /// Sets the content.
100    ///
101    /// Defaults to no content.
102    pub fn content(mut self, content: impl Into<String>) -> Self {
103        self.0.content = Some(content.into());
104
105        self
106    }
107
108    /// Sets the embeds.
109    ///
110    /// Defaults to no embeds.
111    pub fn embeds(mut self, embeds: impl IntoIterator<Item = Embed>) -> Self {
112        self.0.embeds = Some(FromIterator::from_iter(embeds));
113
114        self
115    }
116
117    /// Sets the message flags.
118    ///
119    /// Defaults to no flags.
120    pub fn flags(mut self, flags: MessageFlags) -> Self {
121        self.0.flags = Some(flags);
122
123        self
124    }
125
126    /// Sets whether TTS is used.
127    ///
128    /// Defaults to `false`.
129    pub fn tts(mut self, tts: bool) -> Self {
130        self.0.tts = Some(tts);
131
132        self
133    }
134
135    /// Sets the poll.
136    ///
137    /// Defaults to no poll.
138    pub fn poll(mut self, poll: Poll) -> Self {
139        self.0.poll = Some(poll);
140
141        self
142    }
143}
144
145impl From<ChannelMessageBuilder> for InteractionResponse {
146    fn from(builder: ChannelMessageBuilder) -> Self {
147        builder.build()
148    }
149}
150
151/// Builder for a [`InteractionResponse`] of type [`InteractionResponseType::Modal`].
152#[derive(Clone, Debug)]
153#[must_use = "builders have no effect if unused"]
154pub struct ModalBuilder(InteractionResponseData);
155
156impl ModalBuilder {
157    /// Creates a new default builder.
158    pub fn new(
159        custom_id: impl Into<String>,
160        title: impl Into<String>,
161        components: impl IntoIterator<Item = impl Into<Component>>,
162    ) -> Self {
163        Self(InteractionResponseData {
164            components: Some(components.into_iter().map(Into::into).collect()),
165            custom_id: Some(custom_id.into()),
166            title: Some(title.into()),
167            ..Default::default()
168        })
169    }
170
171    /// Builds the [`InteractionResponse`].
172    pub fn build(self) -> InteractionResponse {
173        InteractionResponse {
174            kind: InteractionResponseType::Modal,
175            data: Some(self.0),
176        }
177    }
178}
179
180impl From<ModalBuilder> for InteractionResponse {
181    fn from(builder: ModalBuilder) -> Self {
182        builder.build()
183    }
184}
185
186/// Builder for a [`InteractionResponse`] of type [`InteractionResponseType::UpdateMessage`].
187#[derive(Clone, Debug, Default)]
188#[must_use = "builders have no effect if unused"]
189pub struct UpdateMessageBuilder(InteractionResponseData);
190
191impl UpdateMessageBuilder {
192    /// Creates a new default builder.
193    pub fn new() -> Self {
194        Self(InteractionResponseData::default())
195    }
196
197    /// Builds the [`InteractionResponse`].
198    pub fn build(self) -> InteractionResponse {
199        InteractionResponse {
200            kind: InteractionResponseType::UpdateMessage,
201            data: Some(self.0),
202        }
203    }
204
205    /// Sets the allowed mentions filter.
206    ///
207    /// Defaults to no filter.
208    pub fn allowed_mentions(mut self, allowed_mentions: AllowedMentions) -> Self {
209        self.0.allowed_mentions = Some(allowed_mentions);
210
211        self
212    }
213
214    /// Sets the attachments.
215    ///
216    /// Defaults to no attachments.
217    pub fn attachments(mut self, attachments: impl IntoIterator<Item = Attachment>) -> Self {
218        self.0.attachments = Some(FromIterator::from_iter(attachments));
219
220        self
221    }
222
223    /// Sets the components.
224    ///
225    /// Defaults to no components.
226    pub fn components(
227        mut self,
228        components: impl IntoIterator<Item = impl Into<Component>>,
229    ) -> Self {
230        self.0.components = Some(components.into_iter().map(Into::into).collect());
231
232        self
233    }
234
235    /// Sets the content.
236    ///
237    /// Defaults to no content.
238    pub fn content(mut self, content: impl Into<String>) -> Self {
239        self.0.content = Some(content.into());
240
241        self
242    }
243
244    /// Sets the embeds.
245    ///
246    /// Defaults to no embeds.
247    pub fn embeds(mut self, embeds: impl IntoIterator<Item = Embed>) -> Self {
248        self.0.embeds = Some(FromIterator::from_iter(embeds));
249
250        self
251    }
252
253    /// Sets the message flags.
254    ///
255    /// Defaults to no flags.
256    pub fn flags(mut self, flags: MessageFlags) -> Self {
257        self.0.flags = Some(flags);
258
259        self
260    }
261
262    /// Sets whether TTS is used.
263    ///
264    /// Defaults to `false`.
265    pub fn tts(mut self, tts: bool) -> Self {
266        self.0.tts = Some(tts);
267
268        self
269    }
270
271    /// Sets the poll.
272    ///
273    /// Defaults to no poll.
274    pub fn poll(mut self, poll: Poll) -> Self {
275        self.0.poll = Some(poll);
276
277        self
278    }
279}
280
281impl From<UpdateMessageBuilder> for InteractionResponse {
282    fn from(builder: UpdateMessageBuilder) -> Self {
283        builder.build()
284    }
285}
286
287#[cfg(test)]
288mod tests {
289    use super::*;
290    use static_assertions::assert_impl_all;
291    use std::fmt::Debug;
292
293    assert_impl_all!(AutocompleteBuilder: Clone, Debug, Send, Sync);
294    assert_impl_all!(ChannelMessageBuilder: Clone, Debug, Default, Send, Sync);
295    assert_impl_all!(ModalBuilder: Clone, Debug, Send, Sync);
296    assert_impl_all!(UpdateMessageBuilder: Clone, Debug, Default, Send, Sync);
297}