use chrono::{DateTime, TimeZone};
use serde_json::Value;
use std::default::Default;
use std::fmt::Display;
use ::internal::prelude::*;
use ::model::Embed;
#[cfg(feature="utils")]
use ::utils::Colour;
#[derive(Clone, Debug)]
pub struct CreateEmbed(pub Map<String, Value>);
impl CreateEmbed {
pub fn author<F>(mut self, f: F) -> Self
where F: FnOnce(CreateEmbedAuthor) -> CreateEmbedAuthor {
let author = f(CreateEmbedAuthor::default()).0;
self.0.insert("author".to_owned(), Value::Object(author));
CreateEmbed(self.0)
}
#[cfg(feature="utils")]
#[inline]
pub fn color<C: Into<Colour>>(self, colour: C) -> Self {
self.colour(colour.into())
}
#[cfg(feature="utils")]
pub fn colour<C: Into<Colour>>(mut self, colour: C) -> Self {
self.0.insert("color".to_owned(), Value::Number(Number::from(colour.into().0 as u64)));
CreateEmbed(self.0)
}
#[cfg(not(feature="utils"))]
#[inline]
pub fn color(self, colour: u32) -> Self {
self.colour(colour)
}
#[cfg(not(feature="utils"))]
pub fn colour(mut self, colour: u32) -> Self {
self.0.insert("color".to_owned(), Value::Number(Number::from(colour)));
CreateEmbed(self.0)
}
pub fn description(mut self, description: &str) -> Self {
self.0.insert("description".to_owned(), Value::String(description.to_owned()));
CreateEmbed(self.0)
}
pub fn field<F>(mut self, f: F) -> Self
where F: FnOnce(CreateEmbedField) -> CreateEmbedField {
let field = f(CreateEmbedField::default()).0;
{
let key = "fields".to_owned();
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.push(Value::Object(field));
self.0.insert("fields".to_owned(), Value::Array(arr));
}
CreateEmbed(self.0)
}
pub fn footer<F>(mut self, f: F) -> Self
where F: FnOnce(CreateEmbedFooter) -> CreateEmbedFooter {
let footer = f(CreateEmbedFooter::default()).0;
self.0.insert("footer".to_owned(), Value::Object(footer));
CreateEmbed(self.0)
}
pub fn image(mut self, url: &str) -> Self {
let image = json!({
"url": url.to_owned()
});
self.0.insert("image".to_owned(), image);
CreateEmbed(self.0)
}
pub fn thumbnail(mut self, url: &str) -> Self {
let thumbnail = json!({
"url": url.to_owned(),
});
self.0.insert("thumbnail".to_owned(), thumbnail);
CreateEmbed(self.0)
}
pub fn timestamp<T: Into<Timestamp>>(mut self, timestamp: T) -> Self {
self.0.insert("timestamp".to_owned(), Value::String(timestamp.into().ts));
CreateEmbed(self.0)
}
pub fn title(mut self, title: &str) -> Self {
self.0.insert("title".to_owned(), Value::String(title.to_owned()));
CreateEmbed(self.0)
}
pub fn url(mut self, url: &str) -> Self {
self.0.insert("url".to_owned(), Value::String(url.to_owned()));
CreateEmbed(self.0)
}
}
impl Default for CreateEmbed {
fn default() -> CreateEmbed {
let mut map = Map::new();
map.insert("type".to_owned(), Value::String("rich".to_owned()));
CreateEmbed(map)
}
}
impl From<Embed> for CreateEmbed {
fn from(embed: Embed) -> CreateEmbed {
let mut b = CreateEmbed::default()
.colour(embed.colour);
if let Some(author) = embed.author {
b = b.author(move |mut a| {
a = a.name(&author.name);
if let Some(icon_url) = author.icon_url {
a = a.icon_url(&icon_url);
}
if let Some(url) = author.url {
a = a.url(&url);
}
a
});
}
if let Some(description) = embed.description {
b = b.description(&description);
}
for field in embed.fields {
b = b.field(move |f| f
.inline(field.inline)
.name(&field.name)
.value(&field.value));
}
if let Some(image) = embed.image {
b = b.image(&image.url);
}
if let Some(timestamp) = embed.timestamp {
b = b.timestamp(timestamp);
}
if let Some(thumbnail) = embed.thumbnail {
b = b.thumbnail(&thumbnail.url);
}
if let Some(url) = embed.url {
b = b.url(&url);
}
if let Some(title) = embed.title {
b = b.title(&title);
}
b
}
}
#[derive(Clone, Debug, Default)]
pub struct CreateEmbedAuthor(pub Map<String, Value>);
impl CreateEmbedAuthor {
pub fn icon_url(mut self, icon_url: &str) -> Self {
self.0.insert("icon_url".to_owned(), Value::String(icon_url.to_owned()));
self
}
pub fn name(mut self, name: &str) -> Self {
self.0.insert("name".to_owned(), Value::String(name.to_owned()));
self
}
pub fn url(mut self, url: &str) -> Self {
self.0.insert("url".to_owned(), Value::String(url.to_owned()));
self
}
}
#[derive(Clone, Debug)]
pub struct CreateEmbedField(pub Map<String, Value>);
impl CreateEmbedField {
pub fn inline(mut self, inline: bool) -> Self {
self.0.insert("inline".to_owned(), Value::Bool(inline));
self
}
pub fn name(mut self, name: &str) -> Self {
self.0.insert("name".to_owned(), Value::String(name.to_owned()));
self
}
pub fn value(mut self, value: &str) -> Self {
self.0.insert("value".to_owned(), Value::String(value.to_owned()));
self
}
}
impl Default for CreateEmbedField {
fn default() -> CreateEmbedField {
let mut map = Map::new();
map.insert("inline".to_owned(), Value::Bool(true));
CreateEmbedField(map)
}
}
#[derive(Clone, Debug, Default)]
pub struct CreateEmbedFooter(pub Map<String, Value>);
impl CreateEmbedFooter {
pub fn icon_url(mut self, icon_url: &str) -> Self {
self.0.insert("icon_url".to_owned(), Value::String(icon_url.to_owned()));
self
}
pub fn text(mut self, text: &str) -> Self {
self.0.insert("text".to_owned(), Value::String(text.to_owned()));
self
}
}
#[derive(Clone, Debug)]
pub struct Timestamp {
pub ts: String,
}
impl From<String> for Timestamp {
fn from(ts: String) -> Self {
Timestamp {
ts: ts,
}
}
}
impl<'a> From<&'a str> for Timestamp {
fn from(ts: &'a str) -> Self {
Timestamp {
ts: ts.to_owned(),
}
}
}
impl<'a, Tz: TimeZone> From<&'a DateTime<Tz>> for Timestamp where Tz::Offset: Display {
fn from(dt: &'a DateTime<Tz>) -> Self {
Timestamp {
ts: dt.to_rfc3339(),
}
}
}