twilight_http/request/channel/message/
delete_messages.rs

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