diff options
Diffstat (limited to 'src/builder/create_embed.rs')
| -rw-r--r-- | src/builder/create_embed.rs | 188 |
1 files changed, 65 insertions, 123 deletions
diff --git a/src/builder/create_embed.rs b/src/builder/create_embed.rs index b38984c..7c4d3d6 100644 --- a/src/builder/create_embed.rs +++ b/src/builder/create_embed.rs @@ -17,10 +17,12 @@ use chrono::{DateTime, TimeZone}; use serde_json::Value; +use std::collections::HashMap; use std::default::Default; use std::fmt::Display; use internal::prelude::*; use model::Embed; +use utils; #[cfg(feature = "utils")] use utils::Colour; @@ -37,7 +39,7 @@ use utils::Colour; /// [`Embed`]: ../model/struct.Embed.html /// [`ExecuteWebhook::embeds`]: struct.ExecuteWebhook.html#method.embeds #[derive(Clone, Debug)] -pub struct CreateEmbed(pub Map<String, Value>); +pub struct CreateEmbed(pub HashMap<&'static str, Value>); impl CreateEmbed { /// Set the author of the embed. @@ -48,9 +50,9 @@ impl CreateEmbed { /// [`CreateEmbedAuthor`]: struct.CreateEmbedAuthor.html pub fn author<F>(mut self, f: F) -> Self where F: FnOnce(CreateEmbedAuthor) -> CreateEmbedAuthor { - let author = f(CreateEmbedAuthor::default()).0; + let map = utils::hashmap_to_json_map(f(CreateEmbedAuthor::default()).0); - self.0.insert("author".to_string(), Value::Object(author)); + self.0.insert("author", Value::Object(map)); CreateEmbed(self.0) } @@ -68,7 +70,7 @@ impl CreateEmbed { #[cfg(feature = "utils")] pub fn colour<C: Into<Colour>>(mut self, colour: C) -> Self { self.0.insert( - "color".to_string(), + "color", Value::Number(Number::from(u64::from(colour.into().0))), ); @@ -88,7 +90,7 @@ impl CreateEmbed { #[cfg(not(feature = "utils"))] pub fn colour(mut self, colour: u32) -> Self { self.0 - .insert("color".to_string(), Value::Number(Number::from(colour))); + .insert("color", Value::Number(Number::from(colour))); CreateEmbed(self.0) } @@ -98,7 +100,7 @@ impl CreateEmbed { /// **Note**: This can't be longer than 2048 characters. pub fn description<D: Display>(mut self, description: D) -> Self { self.0.insert( - "description".to_string(), + "description", Value::String(format!("{}", description)), ); @@ -115,54 +117,35 @@ impl CreateEmbed { /// name and 1024 in a field value and a field is inline by default. /// /// [`CreateEmbedField`]: struct.CreateEmbedField.html - pub fn field<F>(mut self, f: F) -> Self - where F: FnOnce(CreateEmbedField) -> CreateEmbedField { - let field = f(CreateEmbedField::default()).0; - + pub fn field<T, U>(mut self, name: T, value: U, inline: bool) -> Self + where T: Into<String>, U: Into<String> { { - let key = "fields".to_string(); - - let entry = self.0.remove(&key).unwrap_or_else(|| Value::Array(vec![])); - let mut arr = match entry { - Value::Array(inner) => inner, - _ => { - // The type of `entry` should always be a `Value::Array`. - // - // Theoretically this never happens, but you never know. - // - // In the event that it does, just return the current value. - return CreateEmbed(self.0); - }, - }; - arr.push(Value::Object(field)); - - self.0.insert("fields".to_string(), Value::Array(arr)); + let entry = self.0 + .entry("fields") + .or_insert_with(|| Value::Array(vec![])); + + if let Value::Array(ref mut inner) = *entry { + inner.push(json!({ + "inline": inline, + "name": name.into(), + "value": value.into(), + })); + } } - CreateEmbed(self.0) + self } /// Adds multiple fields at once. - pub fn fields<It: IntoIterator<Item=CreateEmbedField>>(mut self, fields: It) -> Self { - let fields = fields - .into_iter() - .map(|m| Value::Object(m.0)) - .collect::<Vec<Value>>(); - - { - let key = "fields".to_string(); - - let entry = self.0.remove(&key).unwrap_or_else(|| Value::Array(vec![])); - let mut arr = match entry { - Value::Array(inner) => inner, - _ => return CreateEmbed(self.0), - }; - arr.extend(fields); - - self.0.insert("fields".to_string(), Value::Array(arr)); + pub fn fields<T, U, It>(mut self, fields: It) -> Self + where It: IntoIterator<Item=(T, U, bool)>, + T: Into<String>, + U: Into<String> { + for field in fields { + self = self.field(field.0.into(), field.1.into(), field.2); } - CreateEmbed(self.0) + self } /// Set the footer of the embed. @@ -174,8 +157,9 @@ impl CreateEmbed { pub fn footer<F>(mut self, f: F) -> Self where F: FnOnce(CreateEmbedFooter) -> CreateEmbedFooter { let footer = f(CreateEmbedFooter::default()).0; + let map = utils::hashmap_to_json_map(footer); - self.0.insert("footer".to_string(), Value::Object(footer)); + self.0.insert("footer", Value::Object(map)); CreateEmbed(self.0) } @@ -186,7 +170,7 @@ impl CreateEmbed { "url": url.to_string() }); - self.0.insert("image".to_string(), image); + self.0.insert("image", image); CreateEmbed(self.0) } @@ -197,7 +181,7 @@ impl CreateEmbed { "url": url.to_string(), }); - self.0.insert("thumbnail".to_string(), thumbnail); + self.0.insert("thumbnail", thumbnail); CreateEmbed(self.0) } @@ -223,8 +207,9 @@ impl CreateEmbed { /// # use serenity::model::*; /// # /// struct Handler; + /// /// impl EventHandler for Handler { - /// fn on_message(&self, _: Context, msg: Message) { + /// fn message(&self, _: Context, msg: Message) { /// if msg.content == "~embed" { /// let _ = msg.channel_id.send_message(|m| m /// .embed(|e| e @@ -234,7 +219,9 @@ impl CreateEmbed { /// } /// } /// - /// let mut client = Client::new("token", Handler); client.start().unwrap(); + /// let mut client = Client::new("token", Handler).unwrap(); + /// + /// client.start().unwrap(); /// ``` /// /// Creating a join-log: @@ -246,23 +233,30 @@ impl CreateEmbed { /// # use serenity::model::*; /// # /// struct Handler; + /// /// impl EventHandler for Handler { +<<<<<<< HEAD + /// fn guild_member_addition(&self, _: Context, guild_id: GuildId, member: Member) { + /// use serenity::client::CACHE; + /// let cache = CACHE.read(); +======= /// fn on_guild_member_addition(&self, _: Context, guild_id: GuildId, member: Member) { /// use serenity::CACHE; /// let cache = CACHE.read().unwrap(); +>>>>>>> v0.4.3 /// /// if let Some(guild) = cache.guild(guild_id) { - /// let guild = guild.read().unwrap(); + /// let guild = guild.read(); /// /// let channel_search = guild /// .channels /// .values() - /// .find(|c| c.read().unwrap().name == "join-log"); + /// .find(|c| c.read().name == "join-log"); /// /// if let Some(channel) = channel_search { - /// let user = member.user.read().unwrap(); + /// let user = member.user.read(); /// - /// let _ = channel.read().unwrap().send_message(|m| m + /// let _ = channel.read().send_message(|m| m /// .embed(|e| { /// let mut e = e /// .author(|a| a.icon_url(&user.face()).name(&user.name)) @@ -279,11 +273,13 @@ impl CreateEmbed { /// } /// } /// - /// let mut client = Client::new("token", Handler); client.start().unwrap(); + /// let mut client = Client::new("token", Handler).unwrap(); + /// + /// client.start().unwrap(); /// ``` pub fn timestamp<T: Into<Timestamp>>(mut self, timestamp: T) -> Self { self.0 - .insert("timestamp".to_string(), Value::String(timestamp.into().ts)); + .insert("timestamp", Value::String(timestamp.into().ts)); CreateEmbed(self.0) } @@ -291,7 +287,7 @@ impl CreateEmbed { /// Set the title of the embed. pub fn title<D: Display>(mut self, title: D) -> Self { self.0 - .insert("title".to_string(), Value::String(format!("{}", title))); + .insert("title", Value::String(format!("{}", title))); CreateEmbed(self.0) } @@ -299,7 +295,7 @@ impl CreateEmbed { /// Set the URL to direct to when clicking on the title. pub fn url(mut self, url: &str) -> Self { self.0 - .insert("url".to_string(), Value::String(url.to_string())); + .insert("url", Value::String(url.to_string())); CreateEmbed(self.0) } @@ -318,8 +314,8 @@ impl CreateEmbed { impl Default for CreateEmbed { /// Creates a builder with default values, setting the `type` to `rich`. fn default() -> CreateEmbed { - let mut map = Map::new(); - map.insert("type".to_string(), Value::String("rich".to_string())); + let mut map = HashMap::new(); + map.insert("type", Value::String("rich".to_string())); CreateEmbed(map) } @@ -353,9 +349,7 @@ impl From<Embed> for CreateEmbed { } for field in embed.fields { - b = b.field(move |f| { - f.inline(field.inline).name(&field.name).value(&field.value) - }); + b = b.field(field.name, field.value, field.inline); } if let Some(image) = embed.image { @@ -391,81 +385,31 @@ impl From<Embed> for CreateEmbed { /// [`CreateEmbed::author`]: struct.CreateEmbed.html#method.author /// [`name`]: #method.name #[derive(Clone, Debug, Default)] -pub struct CreateEmbedAuthor(pub Map<String, Value>); +pub struct CreateEmbedAuthor(pub HashMap<&'static str, Value>); impl CreateEmbedAuthor { /// Set the URL of the author's icon. pub fn icon_url(mut self, icon_url: &str) -> Self { - self.0 - .insert("icon_url".to_string(), Value::String(icon_url.to_string())); + self.0.insert("icon_url", Value::String(icon_url.to_string())); self } /// Set the author's name. pub fn name(mut self, name: &str) -> Self { - self.0 - .insert("name".to_string(), Value::String(name.to_string())); + self.0.insert("name", Value::String(name.to_string())); self } /// Set the author's URL. pub fn url(mut self, url: &str) -> Self { - self.0 - .insert("url".to_string(), Value::String(url.to_string())); + self.0.insert("url", Value::String(url.to_string())); self } } -/// A builder to create a fake [`Embed`] object's field, for use with the -/// [`CreateEmbed::field`] method. -/// -/// This does not require any field be set. `inline` is set to `true` by -/// default. -/// -/// [`Embed`]: ../model/struct.Embed.html -/// [`CreateEmbed::field`]: struct.CreateEmbed.html#method.field -#[derive(Clone, Debug)] -pub struct CreateEmbedField(pub Map<String, Value>); - -impl CreateEmbedField { - /// Set whether the field is inlined. Set to true by default. - pub fn inline(mut self, inline: bool) -> Self { - self.0.insert("inline".to_string(), Value::Bool(inline)); - - self - } - - /// Set the field's name. It can't be longer than 256 characters. - pub fn name<D: Display>(mut self, name: D) -> Self { - self.0 - .insert("name".to_string(), Value::String(format!("{}", name))); - - self - } - - /// Set the field's value. It can't be longer than 1024 characters. - pub fn value<D: Display>(mut self, value: D) -> Self { - self.0 - .insert("value".to_string(), Value::String(format!("{}", value))); - - self - } -} - -impl Default for CreateEmbedField { - /// Creates a builder with default values, setting the value of `inline` to - /// `true`. - fn default() -> CreateEmbedField { - let mut map = Map::new(); - map.insert("inline".to_string(), Value::Bool(true)); - - CreateEmbedField(map) - } -} - /// A builder to create a fake [`Embed`] object's footer, for use with the /// [`CreateEmbed::footer`] method. /// @@ -474,21 +418,19 @@ impl Default for CreateEmbedField { /// [`Embed`]: ../model/struct.Embed.html /// [`CreateEmbed::footer`]: struct.CreateEmbed.html#method.footer #[derive(Clone, Debug, Default)] -pub struct CreateEmbedFooter(pub Map<String, Value>); +pub struct CreateEmbedFooter(pub HashMap<&'static str, Value>); impl CreateEmbedFooter { /// Set the icon URL's value. This only supports HTTP(S). pub fn icon_url(mut self, icon_url: &str) -> Self { - self.0 - .insert("icon_url".to_string(), Value::String(icon_url.to_string())); + self.0.insert("icon_url", Value::String(icon_url.to_string())); self } /// Set the footer's text. pub fn text<D: Display>(mut self, text: D) -> Self { - self.0 - .insert("text".to_string(), Value::String(format!("{}", text))); + self.0.insert("text", Value::String(format!("{}", text))); self } |