aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/error.rs3
-rw-r--r--src/constants.rs4
-rw-r--r--src/model/channel/channel_id.rs9
-rw-r--r--src/model/channel/message.rs65
-rw-r--r--src/utils/macros.rs6
5 files changed, 75 insertions, 12 deletions
diff --git a/src/client/error.rs b/src/client/error.rs
index 6a18b7a..225f2d3 100644
--- a/src/client/error.rs
+++ b/src/client/error.rs
@@ -57,6 +57,9 @@ pub enum Error {
/// When attempting to delete a number of days' worth of messages that is
/// not allowed.
DeleteMessageDaysAmount(u8),
+ /// Indicates that the textual content of an embed exceeds the maximum
+ /// length.
+ EmbedTooLarge(u64),
/// When there is an error from Discord for a specific action, such as
/// [`ErrorCode::EditByOtherAuthor`]. This is a friendlier representation of
/// the numerical error codes Discord provides.
diff --git a/src/constants.rs b/src/constants.rs
index 0ec973c..de670c9 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -1,5 +1,5 @@
-use std::result::Result as StdResult;
-
+/// The maximum length of the textual size of an embed.
+pub const EMBED_MAX_LENGTH: u16 = 4000;
/// The gateway version used by the library. The gateway URI is retrieved via
/// the REST API.
pub const GATEWAY_VERSION: u8 = 6;
diff --git a/src/model/channel/channel_id.rs b/src/model/channel/channel_id.rs
index 5b238b0..79a6fa4 100644
--- a/src/model/channel/channel_id.rs
+++ b/src/model/channel/channel_id.rs
@@ -418,13 +418,8 @@ impl ChannelId {
where F: FnOnce(CreateMessage) -> CreateMessage {
let map = f(CreateMessage::default()).0;
- if let Some(content) = map.get(&"content".to_owned()) {
- if let Value::String(ref content) = *content {
- if let Some(length_over) = Message::overflow_length(content) {
- return Err(Error::Client(ClientError::MessageTooLong(length_over)));
- }
- }
- }
+ Message::check_content_length(&map)?;
+ Message::check_embed_length(&map)?;
rest::send_message(self.0, &Value::Object(map))
}
diff --git a/src/model/channel/message.rs b/src/model/channel/message.rs
index 6bbb1a2..11855b8 100644
--- a/src/model/channel/message.rs
+++ b/src/model/channel/message.rs
@@ -431,6 +431,71 @@ impl Message {
-> Result<Vec<User>> where R: Into<ReactionType>, U: Into<UserId> {
self.reaction_users(reaction_type, limit, after)
}
+
+ #[doc(hidden)]
+ pub fn check_content_length(map: &JsonMap) -> Result<()> {
+ if let Some(content) = map.get("content") {
+ if let Value::String(ref content) = *content {
+ if let Some(length_over) = Message::overflow_length(content) {
+ return Err(Error::Client(ClientError::MessageTooLong(length_over)));
+ }
+ }
+ }
+
+ Ok(())
+ }
+
+ #[doc(hidden)]
+ pub fn check_embed_length(map: &JsonMap) -> Result<()> {
+ let embed = match map.get("embed") {
+ Some(&Value::Object(ref value)) => value,
+ _ => return Ok(()),
+ };
+
+ let mut total: usize = 0;
+
+ if let Some(&Value::Object(ref author)) = embed.get("author") {
+ if let Some(&Value::Object(ref name)) = author.get("name") {
+ total += name.len();
+ }
+ }
+
+ if let Some(&Value::String(ref description)) = embed.get("description") {
+ total += description.len();
+ }
+
+ if let Some(&Value::Array(ref fields)) = embed.get("fields") {
+ for field_as_value in fields {
+ if let Value::Object(ref field) = *field_as_value {
+ if let Some(&Value::String(ref field_name)) = field.get("name") {
+ total += field_name.len();
+ }
+
+ if let Some(&Value::String(ref field_value)) = field.get("value") {
+ total += field_value.len();
+ }
+ }
+ }
+ }
+
+ if let Some(&Value::Object(ref footer)) = embed.get("footer") {
+ if let Some(&Value::String(ref text)) = footer.get("text") {
+ total += text.len();
+ }
+ }
+
+ if let Some(&Value::String(ref title)) = embed.get("title") {
+ total += title.len();
+ }
+
+ if total > constants::EMBED_MAX_LENGTH as usize {
+ Ok(())
+ } else {
+ let overflow = constants::EMBED_MAX_LENGTH as u64 - total as u64;
+
+ Err(Error::Client(ClientError::EmbedTooLarge(overflow)))
+ }
+ }
}
impl From<Message> for MessageId {
diff --git a/src/utils/macros.rs b/src/utils/macros.rs
index be94046..27b3a9b 100644
--- a/src/utils/macros.rs
+++ b/src/utils/macros.rs
@@ -128,7 +128,7 @@ macro_rules! enum_number {
}
impl ::serde::Serialize for $name {
- fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
+ fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error>
where S: ::serde::Serializer
{
// Serialize the enum as a u64.
@@ -137,7 +137,7 @@ macro_rules! enum_number {
}
impl ::serde::Deserialize for $name {
- fn deserialize<D>(deserializer: D) -> StdResult<Self, D::Error>
+ fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
where D: ::serde::Deserializer
{
struct Visitor;
@@ -149,7 +149,7 @@ macro_rules! enum_number {
formatter.write_str("positive integer")
}
- fn visit_u64<E>(self, value: u64) -> StdResult<$name, E>
+ fn visit_u64<E>(self, value: u64) -> ::std::result::Result<$name, E>
where E: ::serde::de::Error
{
// Rust does not come with a simple way of converting a