use serenity::builder::{CreateEmbed, CreateEmbedAuthor, CreateEmbedFooter};
use serenity::model::channel::EmbedField;
use serenity::model::Timestamp;
use serenity::utils::Colour;
#[derive(Clone, Debug)]
pub struct EmbedAuthorBuilder {
pub icon_url: Option<String>,
pub name: String,
pub url: Option<String>,
}
impl EmbedAuthorBuilder {
pub fn new<S: ToString>(name: S) -> Self {
Self {
icon_url: None,
name: name.to_string(),
url: None,
}
}
pub fn set_icon_url<S: ToString>(&mut self, icon_url: S) -> &mut Self {
self.icon_url = Some(icon_url.to_string());
self
}
pub fn set_name<S: ToString>(&mut self, name: S) -> &mut Self {
self.name = name.to_string();
self
}
pub fn set_url<S: ToString>(&mut self, url: S) -> &mut Self {
self.url = Some(url.to_string());
self
}
pub fn to_create_embed_author(&self) -> CreateEmbedAuthor {
self.into()
}
}
impl From<EmbedAuthorBuilder> for CreateEmbedAuthor {
fn from(author_builder: EmbedAuthorBuilder) -> Self {
let mut author = CreateEmbedAuthor::default();
author.name(author_builder.name);
if let Some(value) = author_builder.icon_url {
author.icon_url(value);
}
if let Some(value) = author_builder.url {
author.url(value);
}
author
}
}
impl From<&EmbedAuthorBuilder> for CreateEmbedAuthor {
fn from(author_builder: &EmbedAuthorBuilder) -> Self {
let mut author = CreateEmbedAuthor::default();
author.name(&author_builder.name);
if let Some(value) = &author_builder.icon_url {
author.icon_url(value);
}
if let Some(value) = &author_builder.url {
author.url(value);
}
author
}
}
#[derive(Clone, Debug)]
pub struct EmbedFooterBuilder {
pub icon_url: Option<String>,
pub text: String,
}
impl EmbedFooterBuilder {
pub fn new<S: ToString>(text: S) -> Self {
Self {
icon_url: None,
text: text.to_string(),
}
}
pub fn set_icon_url<S: ToString>(&mut self, icon_url: S) -> &mut Self {
self.icon_url = Some(icon_url.to_string());
self
}
pub fn set_text<S: ToString>(&mut self, text: S) -> &mut Self {
self.text = text.to_string();
self
}
pub fn to_create_embed_footer(&self) -> CreateEmbedFooter {
self.into()
}
}
impl From<EmbedFooterBuilder> for CreateEmbedFooter {
fn from(footer_builder: EmbedFooterBuilder) -> Self {
let mut footer = CreateEmbedFooter::default();
footer.text(footer_builder.text);
if let Some(value) = footer_builder.icon_url {
footer.icon_url(value);
}
footer
}
}
impl From<&EmbedFooterBuilder> for CreateEmbedFooter {
fn from(footer_builder: &EmbedFooterBuilder) -> Self {
let mut footer = CreateEmbedFooter::default();
footer.text(&footer_builder.text);
if let Some(value) = &footer_builder.icon_url {
footer.icon_url(value);
}
footer
}
}
#[derive(Clone, Debug)]
pub struct EmbedFieldBuilder {
pub inline: bool,
pub name: String,
pub value: String,
}
impl EmbedFieldBuilder {
pub fn new<T: ToString, U: ToString>(name: T, value: U, inline: bool) -> Self {
Self {
name: name.to_string(),
value: value.to_string(),
inline,
}
}
pub fn set_name<S: ToString>(&mut self, name: S) -> &mut Self {
self.name = name.to_string();
self
}
pub fn set_value<S: ToString>(&mut self, value: S) -> &mut Self {
self.value = value.to_string();
self
}
pub fn set_inline(&mut self, inline: bool) -> &mut Self {
self.inline = inline;
self
}
pub fn insert_to(self, embed: &mut CreateEmbed) -> &mut CreateEmbed {
embed.field(self.name, self.value, self.inline)
}
}
impl From<EmbedFieldBuilder> for EmbedField {
fn from(field: EmbedFieldBuilder) -> Self {
EmbedField::new(field.name, field.value, field.inline)
}
}
impl From<&EmbedFieldBuilder> for EmbedField {
fn from(field: &EmbedFieldBuilder) -> Self {
EmbedField::new(&field.name, &field.value, field.inline)
}
}
#[derive(Clone, Debug, Default)]
pub struct EmbedBuilder {
pub author: Option<EmbedAuthorBuilder>,
pub colour: Option<Colour>,
pub description: Option<String>,
pub fields: Vec<EmbedFieldBuilder>,
pub footer: Option<EmbedFooterBuilder>,
pub image: Option<String>,
pub thumbnail: Option<String>,
pub timestamp: Option<Timestamp>,
pub title: Option<String>,
pub url: Option<String>,
pub attachment: Option<String>,
}
impl EmbedBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn set_attachment<S: ToString>(&mut self, filename: S) -> &mut Self {
let mut filename = filename.to_string();
filename.insert_str(0, "attachment://");
self.attachment = Some(filename);
self
}
pub fn set_author(&mut self, author: EmbedAuthorBuilder) -> &mut Self {
self.author = Some(author);
self
}
pub fn set_author_with<F>(&mut self, f: F) -> &mut Self
where
F: FnOnce(&mut EmbedAuthorBuilder) -> &mut EmbedAuthorBuilder,
{
let mut author = EmbedAuthorBuilder::new("name");
f(&mut author);
self.set_author(author)
}
pub fn set_colour<C: Into<Colour>>(&mut self, colour: C) -> &mut Self {
self.colour = Some(colour.into());
self
}
pub fn set_description<S: ToString>(&mut self, description: S) -> &mut Self {
self.description = Some(description.to_string());
self
}
pub fn add_field<T, U>(&mut self, field: (T, U, bool)) -> &mut Self
where
T: ToString,
U: ToString,
{
self.fields.push(EmbedFieldBuilder::new(field.0, field.1, field.2));
self
}
pub fn add_fields<T, U, It>(&mut self, fields: It) -> &mut Self
where
It: IntoIterator<Item = (T, U, bool)>,
T: ToString,
U: ToString,
{
let mut fields =
fields.into_iter().map(|(n, v, b)| EmbedFieldBuilder::new(n, v, b)).collect::<Vec<_>>();
self.fields.append(&mut fields);
self
}
pub fn set_field_at(&mut self, index: usize, field: EmbedFieldBuilder) -> &mut Self {
if self.fields.len() - 1 > index {
self.fields[index] = field;
}
self
}
pub fn set_footer(&mut self, footer: EmbedFooterBuilder) -> &mut Self {
self.footer = Some(footer);
self
}
pub fn set_footer_with<F>(&mut self, f: F) -> &mut Self
where
F: FnOnce(&mut EmbedFooterBuilder) -> &mut EmbedFooterBuilder,
{
let mut footer = EmbedFooterBuilder::new("text");
f(&mut footer);
self.set_footer(footer)
}
pub fn set_image<S: ToString>(&mut self, url: S) -> &mut Self {
self.image = Some(url.to_string());
self
}
pub fn set_thumbnail<S: ToString>(&mut self, url: S) -> &mut Self {
self.thumbnail = Some(url.to_string());
self
}
pub fn set_timestamp<T: Into<Timestamp>>(&mut self, timestamp: T) -> &mut Self {
self.timestamp = Some(timestamp.into());
self
}
pub fn set_title<S: ToString>(&mut self, title: S) -> &mut Self {
self.title = Some(title.to_string());
self
}
pub fn set_url<S: ToString>(&mut self, url: S) -> &mut Self {
self.url = Some(url.to_string());
self
}
pub fn to_create_embed(&self) -> CreateEmbed {
self.into()
}
}
impl From<EmbedBuilder> for CreateEmbed {
fn from(embed_builder: EmbedBuilder) -> Self {
let mut embed = CreateEmbed::default();
if let Some(author) = embed_builder.author {
embed.author(|f| {
f.0 = author.to_create_embed_author().0;
f
});
}
if let Some(colour) = embed_builder.colour {
embed.colour(colour);
}
if let Some(description) = embed_builder.description {
embed.description(description);
}
for field in embed_builder.fields {
embed.field(field.name, field.value, field.inline);
}
if let Some(footer) = embed_builder.footer {
embed.footer(|f| {
f.0 = footer.to_create_embed_footer().0;
f
});
}
if let Some(image) = embed_builder.image {
embed.image(image);
}
if let Some(thumbnail) = embed_builder.thumbnail {
embed.thumbnail(thumbnail);
}
if let Some(timestamp) = embed_builder.timestamp {
embed.timestamp(timestamp);
}
if let Some(title) = embed_builder.title {
embed.title(title);
}
if let Some(url) = embed_builder.url {
embed.url(url);
}
if let Some(attachment) = embed_builder.attachment {
embed.attachment(attachment);
}
embed
}
}
impl From<&EmbedBuilder> for CreateEmbed {
fn from(embed_builder: &EmbedBuilder) -> Self {
let mut embed = CreateEmbed::default();
if let Some(author) = &embed_builder.author {
embed.author(|f| {
f.0 = author.to_create_embed_author().0;
f
});
}
if let Some(colour) = embed_builder.colour {
embed.colour(colour);
}
if let Some(description) = &embed_builder.description {
embed.description(description);
}
for field in &embed_builder.fields {
embed.field(&field.name, &field.value, field.inline);
}
if let Some(footer) = &embed_builder.footer {
embed.footer(|f| {
f.0 = footer.to_create_embed_footer().0;
f
});
}
if let Some(image) = &embed_builder.image {
embed.image(image);
}
if let Some(thumbnail) = &embed_builder.thumbnail {
embed.thumbnail(thumbnail);
}
if let Some(timestamp) = embed_builder.timestamp {
embed.timestamp(timestamp);
}
if let Some(title) = &embed_builder.title {
embed.title(title);
}
if let Some(url) = &embed_builder.url {
embed.url(url);
}
if let Some(attachment) = &embed_builder.attachment {
embed.attachment(attachment);
}
embed
}
}