twilight_http/request/
try_into_request.rs

1mod private {
2    use crate::request::{
3        application::{
4            command::{
5                create_global_command::{
6                    CreateGlobalChatInputCommand, CreateGlobalMessageCommand,
7                    CreateGlobalUserCommand,
8                },
9                create_guild_command::{
10                    CreateGuildChatInputCommand, CreateGuildMessageCommand, CreateGuildUserCommand,
11                },
12                CreateGlobalCommand, CreateGuildCommand, DeleteGlobalCommand, DeleteGuildCommand,
13                GetCommandPermissions, GetGlobalCommand, GetGlobalCommands, GetGuildCommand,
14                GetGuildCommandPermissions, GetGuildCommands, SetGlobalCommands, SetGuildCommands,
15                UpdateCommandPermissions, UpdateGlobalCommand, UpdateGuildCommand,
16            },
17            emoji::{
18                AddApplicationEmoji, DeleteApplicationEmoji, ListApplicationEmojis,
19                UpdateApplicationEmoji,
20            },
21            interaction::{
22                CreateFollowup, CreateResponse, DeleteFollowup, DeleteResponse, GetFollowup,
23                GetResponse, UpdateFollowup, UpdateResponse,
24            },
25            monetization::{
26                create_test_entitlement::CreateTestEntitlement, get_entitlements::GetEntitlements,
27                DeleteTestEntitlement, GetSKUs,
28            },
29        },
30        channel::{
31            invite::{CreateInvite, DeleteInvite, GetChannelInvites, GetInvite},
32            message::{
33                CreateMessage, CrosspostMessage, DeleteMessage, DeleteMessages, GetChannelMessages,
34                GetChannelMessagesConfigured, GetMessage, UpdateMessage,
35            },
36            reaction::{
37                CreateReaction, DeleteAllReaction, DeleteAllReactions, DeleteReaction, GetReactions,
38            },
39            stage::{
40                CreateStageInstance, DeleteStageInstance, GetStageInstance, UpdateStageInstance,
41            },
42            thread::{
43                create_forum_thread::CreateForumThreadMessage, AddThreadMember, CreateThread,
44                CreateThreadFromMessage, GetJoinedPrivateArchivedThreads,
45                GetPrivateArchivedThreads, GetPublicArchivedThreads, GetThreadMember,
46                GetThreadMembers, JoinThread, LeaveThread, RemoveThreadMember, UpdateThread,
47            },
48            webhook::{
49                CreateWebhook, DeleteWebhook, DeleteWebhookMessage, ExecuteWebhook,
50                ExecuteWebhookAndWait, GetChannelWebhooks, GetWebhook, GetWebhookMessage,
51                UpdateWebhook, UpdateWebhookMessage, UpdateWebhookWithToken,
52            },
53            CreatePin, CreateTypingTrigger, DeleteChannel, DeleteChannelPermission,
54            DeleteChannelPermissionConfigured, DeletePin, FollowNewsChannel, GetChannel, GetPins,
55            UpdateChannel, UpdateChannelPermission,
56        },
57        guild::{
58            auto_moderation::{
59                CreateAutoModerationRule, DeleteAutoModerationRule, GetAutoModerationRule,
60                GetGuildAutoModerationRules, UpdateAutoModerationRule,
61            },
62            ban::{CreateBan, DeleteBan, GetBan, GetBans},
63            emoji::{CreateEmoji, DeleteEmoji, GetEmoji, GetEmojis, UpdateEmoji},
64            integration::{DeleteGuildIntegration, GetGuildIntegrations},
65            member::{
66                AddGuildMember, AddRoleToMember, GetGuildMembers, GetMember, RemoveMember,
67                RemoveRoleFromMember, SearchGuildMembers, UpdateGuildMember,
68            },
69            role::{
70                CreateRole, DeleteRole, GetGuildRoles, GetRole, UpdateRole, UpdateRolePositions,
71            },
72            sticker::{
73                CreateGuildSticker, DeleteGuildSticker, GetGuildSticker, GetGuildStickers,
74                UpdateGuildSticker,
75            },
76            update_guild_onboarding::UpdateGuildOnboarding,
77            user::{
78                GetCurrentUserVoiceState, GetUserVoiceState, UpdateCurrentUserVoiceState,
79                UpdateUserVoiceState,
80            },
81            CreateGuild, CreateGuildChannel, CreateGuildPrune, DeleteGuild, GetActiveThreads,
82            GetAuditLog, GetGuild, GetGuildChannels, GetGuildInvites, GetGuildOnboarding,
83            GetGuildPreview, GetGuildPruneCount, GetGuildVanityUrl, GetGuildVoiceRegions,
84            GetGuildWebhooks, GetGuildWelcomeScreen, GetGuildWidget, GetGuildWidgetSettings,
85            UpdateCurrentMember, UpdateGuild, UpdateGuildChannelPositions, UpdateGuildMfa,
86            UpdateGuildWelcomeScreen, UpdateGuildWidgetSettings,
87        },
88        poll::{EndPoll, GetAnswerVoters},
89        scheduled_event::{
90            CreateGuildExternalScheduledEvent, CreateGuildStageInstanceScheduledEvent,
91            CreateGuildVoiceScheduledEvent, DeleteGuildScheduledEvent, GetGuildScheduledEvent,
92            GetGuildScheduledEventUsers, GetGuildScheduledEvents, UpdateGuildScheduledEvent,
93        },
94        sticker::{GetNitroStickerPacks, GetSticker},
95        template::{
96            CreateGuildFromTemplate, CreateTemplate, DeleteTemplate, GetTemplate, GetTemplates,
97            SyncTemplate, UpdateTemplate,
98        },
99        update_user_application::UpdateCurrentUserApplication,
100        user::{
101            CreatePrivateChannel, GetCurrentUser, GetCurrentUserConnections,
102            GetCurrentUserGuildMember, GetCurrentUserGuilds, GetUser, LeaveGuild,
103            UpdateCurrentUser,
104        },
105        GetCurrentAuthorizationInformation, GetGateway, GetGatewayAuthed, GetUserApplicationInfo,
106        GetVoiceRegions,
107    };
108
109    pub trait Sealed {}
110
111    impl Sealed for AddApplicationEmoji<'_> {}
112    impl Sealed for AddGuildMember<'_> {}
113    impl Sealed for AddRoleToMember<'_> {}
114    impl Sealed for AddThreadMember<'_> {}
115    impl Sealed for CreateAutoModerationRule<'_> {}
116    impl Sealed for CreateBan<'_> {}
117    impl Sealed for CreateEmoji<'_> {}
118    impl Sealed for CreateFollowup<'_> {}
119    impl Sealed for CreateForumThreadMessage<'_> {}
120    impl Sealed for CreateGlobalChatInputCommand<'_> {}
121    impl Sealed for CreateGlobalCommand<'_> {}
122    impl Sealed for CreateGlobalMessageCommand<'_> {}
123    impl Sealed for CreateGlobalUserCommand<'_> {}
124    impl Sealed for CreateGuild<'_> {}
125    impl Sealed for CreateGuildChannel<'_> {}
126    impl Sealed for CreateGuildChatInputCommand<'_> {}
127    impl Sealed for CreateGuildCommand<'_> {}
128    impl Sealed for CreateGuildExternalScheduledEvent<'_> {}
129    impl Sealed for CreateGuildFromTemplate<'_> {}
130    impl Sealed for CreateGuildMessageCommand<'_> {}
131    impl Sealed for CreateGuildPrune<'_> {}
132    impl Sealed for CreateGuildStageInstanceScheduledEvent<'_> {}
133    impl Sealed for CreateGuildSticker<'_> {}
134    impl Sealed for CreateGuildUserCommand<'_> {}
135    impl Sealed for CreateGuildVoiceScheduledEvent<'_> {}
136    impl Sealed for CreateInvite<'_> {}
137    impl Sealed for CreateMessage<'_> {}
138    impl Sealed for CreatePin<'_> {}
139    impl Sealed for CreatePrivateChannel<'_> {}
140    impl Sealed for CreateReaction<'_> {}
141    impl Sealed for CreateResponse<'_> {}
142    impl Sealed for CreateRole<'_> {}
143    impl Sealed for CreateStageInstance<'_> {}
144    impl Sealed for CreateTemplate<'_> {}
145    impl Sealed for CreateTestEntitlement<'_> {}
146    impl Sealed for CreateThread<'_> {}
147    impl Sealed for CreateThreadFromMessage<'_> {}
148    impl Sealed for CreateTypingTrigger<'_> {}
149    impl Sealed for CreateWebhook<'_> {}
150    impl Sealed for CrosspostMessage<'_> {}
151    impl Sealed for DeleteAllReaction<'_> {}
152    impl Sealed for DeleteAllReactions<'_> {}
153    impl Sealed for DeleteAutoModerationRule<'_> {}
154    impl Sealed for DeleteBan<'_> {}
155    impl Sealed for DeleteChannel<'_> {}
156    impl Sealed for DeleteChannelPermission<'_> {}
157    impl Sealed for DeleteChannelPermissionConfigured<'_> {}
158    impl Sealed for DeleteEmoji<'_> {}
159    impl Sealed for DeleteFollowup<'_> {}
160    impl Sealed for DeleteGlobalCommand<'_> {}
161    impl Sealed for DeleteGuild<'_> {}
162    impl Sealed for DeleteGuildCommand<'_> {}
163    impl Sealed for DeleteGuildIntegration<'_> {}
164    impl Sealed for DeleteGuildScheduledEvent<'_> {}
165    impl Sealed for DeleteGuildSticker<'_> {}
166    impl Sealed for DeleteInvite<'_> {}
167    impl Sealed for DeleteMessage<'_> {}
168    impl Sealed for DeleteMessages<'_> {}
169    impl Sealed for DeletePin<'_> {}
170    impl Sealed for DeleteReaction<'_> {}
171    impl Sealed for DeleteResponse<'_> {}
172    impl Sealed for DeleteRole<'_> {}
173    impl Sealed for DeleteStageInstance<'_> {}
174    impl Sealed for DeleteTemplate<'_> {}
175    impl Sealed for DeleteWebhook<'_> {}
176    impl Sealed for DeleteWebhookMessage<'_> {}
177    impl Sealed for DeleteTestEntitlement<'_> {}
178    impl Sealed for DeleteApplicationEmoji<'_> {}
179    impl Sealed for UpdateApplicationEmoji<'_> {}
180    impl Sealed for EndPoll<'_> {}
181    impl Sealed for ExecuteWebhook<'_> {}
182    impl Sealed for ExecuteWebhookAndWait<'_> {}
183    impl Sealed for FollowNewsChannel<'_> {}
184    impl Sealed for GetActiveThreads<'_> {}
185    impl Sealed for ListApplicationEmojis<'_> {}
186    impl Sealed for GetAnswerVoters<'_> {}
187    impl Sealed for GetAuditLog<'_> {}
188    impl Sealed for GetAutoModerationRule<'_> {}
189    impl Sealed for GetBan<'_> {}
190    impl Sealed for GetBans<'_> {}
191    impl Sealed for GetChannel<'_> {}
192    impl Sealed for GetChannelInvites<'_> {}
193    impl Sealed for GetChannelMessages<'_> {}
194    impl Sealed for GetChannelMessagesConfigured<'_> {}
195    impl Sealed for GetChannelWebhooks<'_> {}
196    impl Sealed for GetCommandPermissions<'_> {}
197    impl Sealed for GetCurrentUser<'_> {}
198    impl Sealed for GetCurrentAuthorizationInformation<'_> {}
199    impl Sealed for GetCurrentUserConnections<'_> {}
200    impl Sealed for GetCurrentUserGuildMember<'_> {}
201    impl Sealed for GetCurrentUserGuilds<'_> {}
202    impl Sealed for GetCurrentUserVoiceState<'_> {}
203    impl Sealed for GetEmoji<'_> {}
204    impl Sealed for GetEmojis<'_> {}
205    impl Sealed for GetEntitlements<'_> {}
206    impl Sealed for GetFollowup<'_> {}
207    impl Sealed for GetGateway<'_> {}
208    impl Sealed for GetGatewayAuthed<'_> {}
209    impl Sealed for GetGlobalCommand<'_> {}
210    impl Sealed for GetGlobalCommands<'_> {}
211    impl Sealed for GetGuild<'_> {}
212    impl Sealed for GetGuildAutoModerationRules<'_> {}
213    impl Sealed for GetGuildChannels<'_> {}
214    impl Sealed for GetGuildCommand<'_> {}
215    impl Sealed for GetGuildCommandPermissions<'_> {}
216    impl Sealed for GetGuildCommands<'_> {}
217    impl Sealed for GetGuildIntegrations<'_> {}
218    impl Sealed for GetGuildInvites<'_> {}
219    impl Sealed for GetGuildMembers<'_> {}
220    impl Sealed for GetGuildOnboarding<'_> {}
221    impl Sealed for GetGuildPreview<'_> {}
222    impl Sealed for GetGuildPruneCount<'_> {}
223    impl Sealed for GetGuildRoles<'_> {}
224    impl Sealed for GetGuildScheduledEvent<'_> {}
225    impl Sealed for GetGuildScheduledEventUsers<'_> {}
226    impl Sealed for GetGuildScheduledEvents<'_> {}
227    impl Sealed for GetGuildSticker<'_> {}
228    impl Sealed for GetGuildStickers<'_> {}
229    impl Sealed for GetGuildVanityUrl<'_> {}
230    impl Sealed for GetGuildVoiceRegions<'_> {}
231    impl Sealed for GetGuildWebhooks<'_> {}
232    impl Sealed for GetGuildWelcomeScreen<'_> {}
233    impl Sealed for GetGuildWidget<'_> {}
234    impl Sealed for GetGuildWidgetSettings<'_> {}
235    impl Sealed for GetInvite<'_> {}
236    impl Sealed for GetJoinedPrivateArchivedThreads<'_> {}
237    impl Sealed for GetMember<'_> {}
238    impl Sealed for GetMessage<'_> {}
239    impl Sealed for GetNitroStickerPacks<'_> {}
240    impl Sealed for GetPins<'_> {}
241    impl Sealed for GetPrivateArchivedThreads<'_> {}
242    impl Sealed for GetPublicArchivedThreads<'_> {}
243    impl Sealed for GetReactions<'_> {}
244    impl Sealed for GetResponse<'_> {}
245    impl Sealed for GetRole<'_> {}
246    impl Sealed for GetSKUs<'_> {}
247    impl Sealed for GetStageInstance<'_> {}
248    impl Sealed for GetSticker<'_> {}
249    impl Sealed for GetTemplate<'_> {}
250    impl Sealed for GetTemplates<'_> {}
251    impl Sealed for GetThreadMember<'_> {}
252    impl Sealed for GetThreadMembers<'_> {}
253    impl Sealed for GetUser<'_> {}
254    impl Sealed for GetUserApplicationInfo<'_> {}
255    impl Sealed for GetUserVoiceState<'_> {}
256    impl Sealed for GetVoiceRegions<'_> {}
257    impl Sealed for GetWebhook<'_> {}
258    impl Sealed for GetWebhookMessage<'_> {}
259    impl Sealed for JoinThread<'_> {}
260    impl Sealed for LeaveGuild<'_> {}
261    impl Sealed for LeaveThread<'_> {}
262    impl Sealed for RemoveMember<'_> {}
263    impl Sealed for RemoveRoleFromMember<'_> {}
264    impl Sealed for RemoveThreadMember<'_> {}
265    impl Sealed for SearchGuildMembers<'_> {}
266    impl Sealed for SetGlobalCommands<'_> {}
267    impl Sealed for SetGuildCommands<'_> {}
268    impl Sealed for SyncTemplate<'_> {}
269    impl Sealed for UpdateAutoModerationRule<'_> {}
270    impl Sealed for UpdateChannel<'_> {}
271    impl Sealed for UpdateChannelPermission<'_> {}
272    impl Sealed for UpdateCommandPermissions<'_> {}
273    impl Sealed for UpdateCurrentMember<'_> {}
274    impl Sealed for UpdateCurrentUser<'_> {}
275    impl Sealed for UpdateCurrentUserVoiceState<'_> {}
276    impl Sealed for UpdateEmoji<'_> {}
277    impl Sealed for UpdateFollowup<'_> {}
278    impl Sealed for UpdateGlobalCommand<'_> {}
279    impl Sealed for UpdateGuild<'_> {}
280    impl Sealed for UpdateGuildChannelPositions<'_> {}
281    impl Sealed for UpdateGuildCommand<'_> {}
282    impl Sealed for UpdateGuildMember<'_> {}
283    impl Sealed for UpdateGuildMfa<'_> {}
284    impl Sealed for UpdateGuildOnboarding<'_> {}
285    impl Sealed for UpdateGuildScheduledEvent<'_> {}
286    impl Sealed for UpdateGuildSticker<'_> {}
287    impl Sealed for UpdateGuildWelcomeScreen<'_> {}
288    impl Sealed for UpdateGuildWidgetSettings<'_> {}
289    impl Sealed for UpdateMessage<'_> {}
290    impl Sealed for UpdateResponse<'_> {}
291    impl Sealed for UpdateRole<'_> {}
292    impl Sealed for UpdateRolePositions<'_> {}
293    impl Sealed for UpdateStageInstance<'_> {}
294    impl Sealed for UpdateTemplate<'_> {}
295    impl Sealed for UpdateThread<'_> {}
296    impl Sealed for UpdateUserVoiceState<'_> {}
297    impl Sealed for UpdateWebhook<'_> {}
298    impl Sealed for UpdateWebhookMessage<'_> {}
299    impl Sealed for UpdateWebhookWithToken<'_> {}
300    impl Sealed for UpdateCurrentUserApplication<'_> {}
301}
302
303use super::base::Request;
304use crate::error::Error;
305
306/// Convert a typed request builder into a raw [`Request`].
307///
308/// Converting a typed request builder into a raw request may be preferable in
309/// order to verify whether a request is valid prior to passing it to
310/// [`Client::request`].
311///
312/// Creating raw requests is useful for unit tests and debugging.
313///
314/// # Examples
315///
316/// Convert a [`CreateMessage`] builder into a [`Request`], inspect its body
317/// and route, and then send the request:
318///
319/// ```no_run
320/// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
321/// use std::{env, str};
322/// use twilight_http::{client::Client, request::TryIntoRequest};
323/// use twilight_model::{channel::Message, id::Id};
324///
325/// let client = Client::new(env::var("DISCORD_TOKEN")?);
326/// let channel_id = Id::new(1);
327/// let builder = client
328///     .create_message(channel_id)
329///     .content("This is a test message!")
330///     .tts(false);
331///
332/// let request = builder.try_into_request()?;
333///
334/// println!("{:?} {}", request.method(), request.path());
335///
336/// if let Some(body) = request.body() {
337///     println!("{}", str::from_utf8(body)?);
338/// }
339///
340/// // Because a raw request is being performed, the output type must be
341/// // explicit.
342/// let response = client.request::<Message>(request).await?;
343/// # Ok(()) }
344/// ```
345///
346/// [`Client::request`]: crate::client::Client::request
347/// [`CreateMessage`]: super::channel::message::CreateMessage
348pub trait TryIntoRequest: private::Sealed {
349    /// Try to convert a request builder into a raw [`Request`].
350    ///
351    /// # Errors
352    ///
353    /// Not all typed request builder conversions return an error and may
354    /// instead always succeed. Refer to the documentation for each
355    /// implementation for clarification.
356    ///
357    /// Requests may return an error type of [`ErrorType::CreatingHeader`] if
358    /// creating an audit log header value fails.
359    ///
360    /// Requests may return an error type of [`ErrorType::Json`] if serializing
361    /// a request body fails.
362    ///
363    /// [`ErrorType::CreatingHeader`]: crate::error::ErrorType::CreatingHeader
364    /// [`ErrorType::Json`]: crate::error::ErrorType::Json
365    fn try_into_request(self) -> Result<Request, Error>;
366}
367
368#[cfg(test)]
369mod tests {
370    use super::TryIntoRequest;
371    use crate::{client::Client, request::Method};
372    use static_assertions::assert_obj_safe;
373    use std::error::Error;
374    use twilight_model::id::Id;
375
376    assert_obj_safe!(TryIntoRequest);
377
378    #[test]
379    fn conversion() -> Result<(), Box<dyn Error>> {
380        let client = Client::new("token".to_owned());
381        let channel_id = Id::new(1);
382        let request = client
383            .create_message(channel_id)
384            .content("test")
385            .try_into_request()?;
386
387        assert_eq!(Some(br#"{"content":"test"}"#.as_ref()), request.body());
388        assert!(request.form().is_none());
389        assert_eq!(Method::Post, request.method());
390
391        Ok(())
392    }
393}