Skip to content

Commit

Permalink
feat(http, validate)!: bulk delete message count (twilight-rs#2078)
Browse files Browse the repository at this point in the history
Validate bulk message delete counts by introducing a new
`bulk_delete_messages` in `twilight_validate::channel`.

Part of twilight-rs#1477.
  • Loading branch information
zeylahellyer authored Jan 28, 2023
1 parent e7f2bb2 commit 1299073
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 7 deletions.
12 changes: 10 additions & 2 deletions twilight-http/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1380,12 +1380,20 @@ impl Client {
/// and upper limits. This method will not delete messages older than two
/// weeks. See [Discord Docs/Bulk Delete Messages].
///
/// # Errors
///
/// Returns an error of type
/// [`ChannelValidationErrorType::BulkDeleteMessagesInvalid`] when the number of
/// messages to delete in bulk is invalid.
/// is not between 1 and 120 characters in length.
///
/// [Discord Docs/Bulk Delete Messages]: https://discord.com/developers/docs/resources/channel#bulk-delete-messages
pub const fn delete_messages<'a>(
/// [`ChannelValidationErrorType::BulkDeleteMessagesInvalid`]: twilight_validate::channel::ChannelValidationErrorType::BulkDeleteMessagesInvalid
pub fn delete_messages<'a>(
&'a self,
channel_id: Id<ChannelMarker>,
message_ids: &'a [Id<MessageMarker>],
) -> DeleteMessages<'a> {
) -> Result<DeleteMessages<'a>, ChannelValidationError> {
DeleteMessages::new(self, channel_id, message_ids)
}

Expand Down
15 changes: 10 additions & 5 deletions twilight-http/src/request/channel/message/delete_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ use twilight_model::id::{
marker::{ChannelMarker, MessageMarker},
Id,
};
use twilight_validate::request::{audit_reason as validate_audit_reason, ValidationError};
use twilight_validate::{
channel::{bulk_delete_messages as validate_bulk_delete_messages, ChannelValidationError},
request::{audit_reason as validate_audit_reason, ValidationError},
};

#[derive(Serialize)]
struct DeleteMessagesFields<'a> {
Expand All @@ -35,17 +38,19 @@ pub struct DeleteMessages<'a> {
}

impl<'a> DeleteMessages<'a> {
pub(crate) const fn new(
pub(crate) fn new(
http: &'a Client,
channel_id: Id<ChannelMarker>,
messages: &'a [Id<MessageMarker>],
) -> Self {
Self {
) -> Result<Self, ChannelValidationError> {
validate_bulk_delete_messages(messages.len())?;

Ok(Self {
channel_id,
fields: DeleteMessagesFields { messages },
http,
reason: None,
}
})
}

/// Execute the request, returning a future resolving to a [`Response`].
Expand Down
52 changes: 52 additions & 0 deletions twilight-validate/src/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ use twilight_model::channel::ChannelType;
/// Minimum bitrate of a voice channel.
pub const CHANNEL_BITRATE_MIN: u32 = 8000;

/// Maximum number of bulk messages that can be deleted.
pub const CHANNEL_BULK_DELETE_MESSAGES_MAX: usize = 100;

/// Minimum number of bulk messages that can be deleted.
pub const CHANNEL_BULK_DELETE_MESSAGES_MIN: usize = 2;

/// Maximum length of a forum channel's topic.
pub const CHANNEL_FORUM_TOPIC_LENGTH_MAX: usize = 4096;

Expand Down Expand Up @@ -67,6 +73,13 @@ impl Display for ChannelValidationError {
f.write_str("bitrate is less than ")?;
Display::fmt(&CHANNEL_BITRATE_MIN, f)
}
ChannelValidationErrorType::BulkDeleteMessagesInvalid => {
f.write_str("number of messages deleted in bulk is less than ")?;
Display::fmt(&CHANNEL_BULK_DELETE_MESSAGES_MIN, f)?;
f.write_str(" or greater than ")?;

Display::fmt(&CHANNEL_BULK_DELETE_MESSAGES_MAX, f)
}
ChannelValidationErrorType::ForumTopicInvalid => {
f.write_str("the forum topic is invalid")
}
Expand Down Expand Up @@ -99,6 +112,8 @@ impl Error for ChannelValidationError {}
pub enum ChannelValidationErrorType {
/// The bitrate is less than 8000.
BitrateInvalid,
/// Number of messages being deleted in bulk is invalid.
BulkDeleteMessagesInvalid,
/// The length of the topic is more than 4096 UTF-16 characters.
ForumTopicInvalid,
/// The length of the name is either fewer than 1 UTF-16 characters or
Expand Down Expand Up @@ -139,6 +154,26 @@ pub const fn bitrate(value: u32) -> Result<(), ChannelValidationError> {
}
}

/// Ensure the number of messages to delete in bulk is correct.
///
/// # Errors
///
/// Returns an error of type [`BulkDeleteMessagesInvalid`] if the number of
/// messages to delete in bulk is invalid.
///
/// [`BulkDeleteMessagesInvalid`]: ChannelValidationErrorType::BulkDeleteMessagesInvalid
pub const fn bulk_delete_messages(message_count: usize) -> Result<(), ChannelValidationError> {
if message_count >= CHANNEL_BULK_DELETE_MESSAGES_MIN
&& message_count <= CHANNEL_BULK_DELETE_MESSAGES_MAX
{
Ok(())
} else {
Err(ChannelValidationError {
kind: ChannelValidationErrorType::BulkDeleteMessagesInvalid,
})
}
}

/// Ensure a channel is a thread.
///
/// # Errors
Expand Down Expand Up @@ -269,6 +304,23 @@ pub const fn user_limit(value: u16) -> Result<(), ChannelValidationError> {
mod tests {
use super::*;

#[test]
fn bulk_delete_messages() {
assert!(matches!(
super::bulk_delete_messages(0).unwrap_err().kind(),
ChannelValidationErrorType::BulkDeleteMessagesInvalid,
));
assert!(matches!(
super::bulk_delete_messages(1).unwrap_err().kind(),
ChannelValidationErrorType::BulkDeleteMessagesInvalid,
));
assert!(super::bulk_delete_messages(100).is_ok());
assert!(matches!(
super::bulk_delete_messages(101).unwrap_err().kind(),
ChannelValidationErrorType::BulkDeleteMessagesInvalid,
));
}

#[test]
fn channel_bitrate() {
assert!(bitrate(8000).is_ok());
Expand Down

0 comments on commit 1299073

Please sign in to comment.