Skip to main content

twilight_http/request/channel/message/
delete_messages.rs

1#[cfg(not(target_os = "wasi"))]
2use crate::response::{Response, ResponseFuture, marker::EmptyBody};
3use crate::{
4    client::Client,
5    error::Error,
6    request::{self, AuditLogReason, Request, TryIntoRequest},
7    routing::Route,
8};
9use serde::Serialize;
10use std::future::IntoFuture;
11use twilight_model::id::{
12    Id,
13    marker::{ChannelMarker, MessageMarker},
14};
15use twilight_validate::{
16    channel::{ChannelValidationError, bulk_delete_messages as validate_bulk_delete_messages},
17    request::{ValidationError, audit_reason as validate_audit_reason},
18};
19
20#[derive(Serialize)]
21struct DeleteMessagesFields<'a> {
22    messages: &'a [Id<MessageMarker>],
23}
24
25/// Delete messages by [`Id<ChannelMarker>`] and a list of [`Id<MessageMarker>`]s.
26///
27/// The number of message IDs must be between 2 and 100. If the supplied message
28/// IDs are invalid, they still count towards the lower and upper limits. This
29/// method will not delete messages older than two weeks. See
30/// [Discord Docs/Bulk Delete Messages].
31///
32/// [Discord Docs/Bulk Delete Messages]: https://discord.com/developers/docs/resources/channel#bulk-delete-messages
33#[must_use = "requests must be configured and executed"]
34pub struct DeleteMessages<'a> {
35    channel_id: Id<ChannelMarker>,
36    fields: Result<DeleteMessagesFields<'a>, ChannelValidationError>,
37    http: &'a Client,
38    reason: Result<Option<&'a str>, ValidationError>,
39}
40
41impl<'a> DeleteMessages<'a> {
42    pub(crate) fn new(
43        http: &'a Client,
44        channel_id: Id<ChannelMarker>,
45        messages: &'a [Id<MessageMarker>],
46    ) -> Self {
47        let fields = Ok(DeleteMessagesFields { messages }).and_then(|fields| {
48            validate_bulk_delete_messages(messages.len())?;
49
50            Ok(fields)
51        });
52
53        Self {
54            channel_id,
55            fields,
56            http,
57            reason: Ok(None),
58        }
59    }
60}
61
62impl<'a> AuditLogReason<'a> for DeleteMessages<'a> {
63    fn reason(mut self, reason: &'a str) -> Self {
64        self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
65
66        self
67    }
68}
69
70#[cfg(not(target_os = "wasi"))]
71impl IntoFuture for DeleteMessages<'_> {
72    type Output = Result<Response<EmptyBody>, Error>;
73
74    type IntoFuture = ResponseFuture<EmptyBody>;
75
76    fn into_future(self) -> Self::IntoFuture {
77        let http = self.http;
78
79        match self.try_into_request() {
80            Ok(request) => http.request(request),
81            Err(source) => ResponseFuture::error(source),
82        }
83    }
84}
85
86impl TryIntoRequest for DeleteMessages<'_> {
87    fn try_into_request(self) -> Result<Request, Error> {
88        let fields = self.fields.map_err(Error::validation)?;
89        let mut request = Request::builder(&Route::DeleteMessages {
90            channel_id: self.channel_id.get(),
91        })
92        .json(&fields);
93
94        if let Some(reason) = self.reason.map_err(Error::validation)? {
95            request = request.headers(request::audit_header(reason)?);
96        }
97
98        request.build()
99    }
100}