disint_model/interaction/
response.rs1use derive_builder::Builder;
2use serde::Serialize;
3
4use super::embed::Embed;
5
6#[derive(Debug)]
7#[non_exhaustive]
8pub enum InteractionResponse {
9 Pong,
10 ChannelMessageWithSource(ApplicationCommandCallbackData),
11 DeferredChannelMessageWithSource,
12}
13
14impl Serialize for InteractionResponse {
15 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
16 where
17 S: serde::Serializer,
18 {
19 InteractionResponseInner::new(self).serialize(s)
20 }
21}
22
23#[derive(Debug, Serialize)]
24pub struct ApplicationCommandCallbackData {
25 tts: Option<bool>,
26 content: Option<String>,
27 embeds: Option<Vec<Embed>>,
28 allowed_mentions: Option<AllowedMentions>,
29}
30
31#[derive(Debug, Default, Builder)]
32#[builder(default)]
33pub struct AllowedMentions {
34 roles: AllowedMentionsKind,
35 users: AllowedMentionsKind,
36 deny_mention_everyone: bool,
37}
38
39impl Serialize for AllowedMentions {
40 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
41 where
42 S: serde::Serializer,
43 {
44 #[derive(Default, Serialize)]
45 struct AllowedMentionsInner<'a> {
46 parse: Vec<&'static str>,
47 roles: Option<&'a [String]>,
48 users: Option<&'a [String]>,
49 }
50
51 let mut inner = AllowedMentionsInner::default();
52 if !self.deny_mention_everyone {
53 inner.parse.push("everyone");
54 }
55 match &self.roles {
56 AllowedMentionsKind::All => inner.parse.push("roles"),
57 AllowedMentionsKind::List(l) => inner.roles = Some(&*l),
58 _ => {}
59 }
60 match &self.users {
61 AllowedMentionsKind::All => inner.parse.push("users"),
62 AllowedMentionsKind::List(l) => inner.users = Some(&*l),
63 _ => {}
64 }
65
66 inner.serialize(s)
67 }
68}
69
70#[derive(Clone, Debug)]
71pub enum AllowedMentionsKind {
72 All,
73 List(Vec<String>),
74 None,
75}
76
77impl AllowedMentionsKind {
78 pub fn new() -> Self {
79 Self::default()
80 }
81}
82
83impl std::iter::FromIterator<String> for AllowedMentionsKind {
84 fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
85 Self::List(<Vec<_> as std::iter::FromIterator<_>>::from_iter(iter))
86 }
87}
88
89impl Default for AllowedMentionsKind {
90 fn default() -> Self {
91 Self::All
92 }
93}
94
95#[derive(Serialize)]
96struct InteractionResponseInner<'a> {
97 #[serde(rename = "type")]
98 ty: i32,
99 data: Option<&'a ApplicationCommandCallbackData>,
100}
101
102impl<'a> InteractionResponseInner<'a> {
103 fn new(val: &'a InteractionResponse) -> Self {
104 use InteractionResponse::*;
105
106 let (ty, data) = match val {
107 Pong => (1, None),
108 ChannelMessageWithSource(data) => (4, Some(data)),
109 DeferredChannelMessageWithSource => (5, None),
110 };
111
112 Self { ty, data }
113 }
114}
115
116#[derive(Debug)]
117pub struct InteractionResponseBuilder<State>(State);
118
119#[derive(Debug)]
120pub struct Pong;
121
122#[derive(Debug)]
123pub struct Deferred;
124
125#[derive(Debug, Default)]
126pub struct ChannelMessageNoContent {
127 tts: Option<bool>,
128 embeds: Option<Vec<Embed>>,
129 allowed_mentions: Option<AllowedMentions>,
130}
131
132#[derive(Debug)]
133pub struct ChannelMessage {
134 content: Option<String>,
135 tts: Option<bool>,
136 embeds: Option<Vec<Embed>>,
137 allowed_mentions: Option<AllowedMentions>,
138}
139
140impl InteractionResponseBuilder<Pong> {
141 pub fn pong() -> Self {
142 Self(Pong)
143 }
144
145 pub fn finish(self) -> InteractionResponse {
146 InteractionResponse::Pong
147 }
148}
149
150impl InteractionResponseBuilder<Deferred> {
151 pub fn deferred() -> Self {
152 Self(Deferred)
153 }
154
155 pub fn finish(self) -> InteractionResponse {
156 InteractionResponse::DeferredChannelMessageWithSource
157 }
158}
159
160impl InteractionResponseBuilder<ChannelMessageNoContent> {
161 pub fn channel_message() -> Self {
162 Self(ChannelMessageNoContent::default())
163 }
164
165 pub fn content(self, content: impl Into<String>) -> InteractionResponseBuilder<ChannelMessage> {
166 let ChannelMessageNoContent {
167 tts,
168 embeds,
169 allowed_mentions,
170 } = self.0;
171
172 InteractionResponseBuilder(ChannelMessage {
173 content: Some(content.into()),
174 tts,
175 embeds,
176 allowed_mentions,
177 })
178 }
179
180 pub fn tts(mut self, tts: bool) -> Self {
181 self.0.tts = Some(tts);
182 self
183 }
184
185 pub fn embed(self, embed: Embed) -> InteractionResponseBuilder<ChannelMessage> {
186 let ChannelMessageNoContent {
187 tts,
188 mut embeds,
189 allowed_mentions,
190 } = self.0;
191
192 embeds
193 .get_or_insert_with(Vec::new)
194 .push(embed);
195
196 InteractionResponseBuilder(ChannelMessage {
197 content: None,
198 tts,
199 embeds,
200 allowed_mentions,
201 })
202 }
203
204 pub fn allowed_mentions(mut self, allowed_mentions: AllowedMentions) -> Self {
205 self.0.allowed_mentions = Some(allowed_mentions);
206 self
207 }
208}
209
210impl InteractionResponseBuilder<ChannelMessage> {
211 pub fn finish(self) -> InteractionResponse {
212 let ChannelMessage {
213 content,
214 tts,
215 embeds,
216 allowed_mentions,
217 } = self.0;
218
219 let data = ApplicationCommandCallbackData {
220 tts,
221 content,
222 embeds,
223 allowed_mentions,
224 };
225
226 InteractionResponse::ChannelMessageWithSource(data)
227 }
228
229 pub fn content(mut self, content: impl Into<String>) -> Self {
230 self.0.content = Some(content.into());
231 self
232 }
233
234 pub fn tts(mut self, tts: bool) -> Self {
235 self.0.tts = Some(tts);
236 self
237 }
238
239 pub fn embed(mut self, embed: Embed) -> Self {
240 self.0
241 .embeds
242 .get_or_insert_with(Vec::new)
243 .push(embed);
244 self
245 }
246
247 pub fn allowed_mentions(mut self, allowed_mentions: AllowedMentions) -> Self {
248 self.0.allowed_mentions = Some(allowed_mentions);
249 self
250 }
251}