use twilight_model::channel::message::{
EmojiReactionType,
component::{Button, ButtonStyle},
};
use twilight_validate::component::{ComponentValidationError, button};
#[derive(Clone, Debug, Eq, PartialEq)]
#[must_use = "must be built into a button"]
pub struct ButtonBuilder(Button);
impl ButtonBuilder {
pub const fn new(style: ButtonStyle) -> Self {
Self(Button {
custom_id: None,
disabled: false,
emoji: None,
label: None,
style,
url: None,
id: None,
sku_id: None,
})
}
pub fn custom_id(mut self, custom_id: impl Into<String>) -> Self {
self.0.custom_id.replace(custom_id.into());
self
}
pub const fn disabled(mut self, disabled: bool) -> Self {
self.0.disabled = disabled;
self
}
pub fn emoji(mut self, emoji: EmojiReactionType) -> Self {
self.0.emoji.replace(emoji);
self
}
pub fn url(mut self, url: impl Into<String>) -> Self {
self.0.url.replace(url.into());
self
}
pub fn label(mut self, label: impl Into<String>) -> Self {
self.0.label.replace(label.into());
self
}
pub fn validate(self) -> Result<Self, ComponentValidationError> {
button(&self.0)?;
Ok(self)
}
pub fn build(self) -> Button {
self.0
}
}
impl From<ButtonBuilder> for Button {
fn from(builder: ButtonBuilder) -> Self {
builder.build()
}
}
#[cfg(test)]
mod tests {
use super::*;
use static_assertions::assert_impl_all;
use std::fmt::Debug;
assert_impl_all!(ButtonBuilder: Clone, Debug, Eq, PartialEq, Send, Sync);
assert_impl_all!(Button: From<ButtonBuilder>);
#[test]
fn builder() {
let expected = Button {
custom_id: None,
disabled: false,
emoji: None,
label: None,
style: ButtonStyle::Primary,
url: None,
id: None,
sku_id: None,
};
let actual = ButtonBuilder::new(ButtonStyle::Primary).build();
assert_eq!(actual, expected);
}
}