Skip to content

Commit

Permalink
add embed validation
Browse files Browse the repository at this point in the history
Add embed validation for creating and updating messages. This checks the
the author name, description, field names, field values, footer text,
and title lengths to ensure they aren't too long. The total number of
fields is checked as well as the total combined length of all of the
above.

This addresses comment
<#167 (comment)>.

Limits are referenced in the documentation to point to
<https://discord.com/developers/docs/resources/channel#embed-limits>.

Signed-off-by: Vivian Hellyer <vivian@hellyer.dev>
  • Loading branch information
zeylahellyer committed May 26, 2020
1 parent a62838f commit 81d8313
Show file tree
Hide file tree
Showing 5 changed files with 496 additions and 8 deletions.
2 changes: 1 addition & 1 deletion http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ percent-encoding = "2.1"
url = "2"

[dev-dependencies]
tokio = "0.2"
tokio = { features = ["macros"], version = "0.2" }
23 changes: 20 additions & 3 deletions http/src/request/channel/message/create_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,30 @@ use twilight_model::{
#[derive(Clone, Debug)]
pub enum CreateMessageError {
ContentInvalid,
EmbedTooLarge { source: EmbedValidationError },
}

impl Display for CreateMessageError {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
Self::ContentInvalid => f.write_str("the message content is invalid"),
Self::EmbedTooLarge {
..
} => f.write_str("the embed's contents are too long"),
}
}
}

impl Error for CreateMessageError {}
impl Error for CreateMessageError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::ContentInvalid => None,
Self::EmbedTooLarge {
source,
} => Some(source),
}
}
}

#[derive(Default, Serialize)]
pub(crate) struct CreateMessageFields {
Expand Down Expand Up @@ -85,10 +98,14 @@ impl<'a> CreateMessage<'a> {
Ok(self)
}

pub fn embed(mut self, embed: Embed) -> Self {
pub fn embed(mut self, embed: Embed) -> Result<Self, CreateMessageError> {
validate::embed(&embed).map_err(|source| CreateMessageError::EmbedTooLarge {
source,
})?;

self.fields.embed.replace(embed);

self
Ok(self)
}

pub fn allowed_mentions(
Expand Down
1 change: 1 addition & 0 deletions http/src/request/channel/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ pub use self::{
get_message::GetMessage,
update_message::UpdateMessage,
};
pub use super::super::validate::EmbedValidationError;
31 changes: 27 additions & 4 deletions http/src/request/channel/message/update_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,30 @@ use twilight_model::{
#[derive(Clone, Debug)]
pub enum UpdateMessageError {
ContentInvalid,
EmbedTooLarge { source: EmbedValidationError },
}

impl Display for UpdateMessageError {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
Self::ContentInvalid => f.write_str("the message content is invalid"),
Self::EmbedTooLarge {
..
} => f.write_str("the embed's contents are too long"),
}
}
}

impl Error for UpdateMessageError {}
impl Error for UpdateMessageError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::ContentInvalid => None,
Self::EmbedTooLarge {
source,
} => Some(source),
}
}
}

#[derive(Default, Serialize)]
struct UpdateMessageFields {
Expand Down Expand Up @@ -129,10 +142,20 @@ impl<'a> UpdateMessage<'a> {
/// Set the embed of the message.
///
/// Pass `None` if you want to remove the message embed.
pub fn embed(mut self, embed: impl Into<Option<Embed>>) -> Self {
self.fields.embed.replace(embed.into());
pub fn embed(self, embed: impl Into<Option<Embed>>) -> Result<Self, UpdateMessageError> {
self._embed(embed.into())
}

self
fn _embed(mut self, embed: Option<Embed>) -> Result<Self, UpdateMessageError> {
if let Some(embed) = embed.as_ref() {
validate::embed(&embed).map_err(|source| UpdateMessageError::EmbedTooLarge {
source,
})?;
}

self.fields.embed.replace(embed);

Ok(self)
}

fn start(&mut self) -> Result<()> {
Expand Down
Loading

0 comments on commit 81d8313

Please sign in to comment.