use twilight_model::{
channel::{
ChannelType,
message::{
Component,
EmojiReactionType,
component::{
ActionRow,
Button,
ButtonStyle,
SelectDefaultValue,
SelectMenu,
SelectMenuOption,
SelectMenuType,
TextInput,
TextInputStyle,
},
},
},
id::{
Id,
marker::{EmojiMarker, SkuMarker},
},
};
#[cfg(doc)]
use crate::builder::InteractionResponseBuilder;
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct ButtonBuilder {
custom_id: Option<String>,
disabled: bool,
emoji: Option<EmojiReactionType>,
label: Option<String>,
sku_id: Option<Id<SkuMarker>>,
style: ButtonStyle,
url: Option<String>,
}
impl ButtonBuilder {
#[must_use]
pub fn build(self) -> Button {
Button {
custom_id: self.custom_id,
disabled: self.disabled,
emoji: self.emoji,
label: self.label,
sku_id: self.sku_id,
style: self.style,
url: self.url,
}
}
#[must_use]
pub fn custom_emoji(
mut self,
name: Option<String>,
id: Id<EmojiMarker>,
animated: bool,
) -> Self {
self.emoji = Some(EmojiReactionType::Custom { animated, id, name });
self
}
#[must_use]
pub const fn disable(mut self) -> Self {
self.disabled = true;
self
}
#[must_use]
pub fn unicode_emoji(mut self, emoji: String) -> Self {
self.emoji = Some(EmojiReactionType::Unicode { name: emoji });
self
}
#[must_use]
pub const fn with_custom_id(custom_id: String, label: String, style: ButtonStyle) -> Self {
Self {
custom_id: Some(custom_id),
disabled: false,
emoji: None,
label: Some(label),
sku_id: None,
style,
url: None,
}
}
#[must_use]
pub const fn with_sku_id(sku_id: Id<SkuMarker>) -> Self {
Self {
custom_id: None,
disabled: false,
emoji: None,
label: None,
sku_id: Some(sku_id),
style: ButtonStyle::Premium,
url: None,
}
}
#[must_use]
pub const fn with_url(url: String, label: String) -> Self {
Self {
custom_id: None,
disabled: false,
emoji: None,
label: Some(label),
sku_id: None,
style: ButtonStyle::Link,
url: Some(url),
}
}
}
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct ComponentsBuilder {
action_rows: Vec<ActionRow>,
}
impl ComponentsBuilder {
pub fn build(self) -> Vec<Component> {
self.action_rows
.into_iter()
.map(Component::ActionRow)
.collect()
}
#[must_use]
pub fn buttons(mut self, buttons: Vec<Button>) -> Self {
self.action_rows.push(ActionRow {
components: buttons.into_iter().map(Component::Button).collect(),
});
self
}
#[must_use]
pub const fn new() -> Self {
Self {
action_rows: vec![],
}
}
#[must_use]
pub fn select_menu(mut self, select_menu: SelectMenu) -> Self {
self.action_rows.push(ActionRow {
components: vec![Component::SelectMenu(select_menu)],
});
self
}
}
impl Default for ComponentsBuilder {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct SelectMenuBuilder {
channel_types: Option<Vec<ChannelType>>,
custom_id: String,
default_values: Option<Vec<SelectDefaultValue>>,
disabled: bool,
kind: SelectMenuType,
max_values: Option<u8>,
min_values: Option<u8>,
options: Option<Vec<SelectMenuOption>>,
placeholder: Option<String>,
}
impl SelectMenuBuilder {
#[must_use]
pub fn build(self) -> SelectMenu {
SelectMenu {
channel_types: self.channel_types,
custom_id: self.custom_id,
disabled: self.disabled,
default_values: self.default_values,
kind: self.kind,
max_values: self.max_values,
min_values: self.min_values,
options: self.options,
placeholder: self.placeholder,
}
}
#[must_use]
pub fn default_values(mut self, default_values: Vec<SelectDefaultValue>) -> Self {
self.default_values = Some(default_values);
self
}
#[must_use]
pub const fn disable(mut self) -> Self {
self.disabled = true;
self
}
#[must_use]
pub const fn max_values(mut self, max_values: u8) -> Self {
self.max_values = Some(max_values);
self
}
#[must_use]
pub const fn min_values(mut self, min_values: u8) -> Self {
self.min_values = Some(min_values);
self
}
#[must_use]
pub fn placeholder(mut self, placeholder: String) -> Self {
self.placeholder = Some(placeholder);
self
}
#[must_use]
pub const fn with_channel_types(
custom_id: String,
channel_types: Option<Vec<ChannelType>>,
) -> Self {
Self {
channel_types,
custom_id,
disabled: false,
default_values: None,
kind: SelectMenuType::Channel,
max_values: None,
min_values: None,
options: None,
placeholder: None,
}
}
#[must_use]
pub const fn with_kind(custom_id: String, kind: SelectMenuType) -> Self {
Self {
channel_types: None,
custom_id,
disabled: false,
default_values: None,
kind,
max_values: None,
min_values: None,
options: None,
placeholder: None,
}
}
#[must_use]
pub const fn with_options(custom_id: String, options: Vec<SelectMenuOption>) -> Self {
Self {
channel_types: None,
custom_id,
disabled: false,
default_values: None,
kind: SelectMenuType::Text,
max_values: None,
min_values: None,
options: Some(options),
placeholder: None,
}
}
}
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct SelectMenuOptionBuilder {
default: bool,
description: Option<String>,
emoji: Option<EmojiReactionType>,
label: String,
value: String,
}
impl SelectMenuOptionBuilder {
#[must_use]
pub fn build(self) -> SelectMenuOption {
SelectMenuOption {
default: self.default,
description: self.description,
emoji: self.emoji,
label: self.label,
value: self.value,
}
}
#[must_use]
pub fn custom_emoji(mut self, name: String, id: Id<EmojiMarker>, animated: bool) -> Self {
self.emoji = Some(EmojiReactionType::Custom {
animated,
id,
name: Some(name),
});
self
}
#[must_use]
pub const fn default(mut self) -> Self {
self.default = true;
self
}
#[must_use]
pub fn description(mut self, description: String) -> Self {
self.description = Some(description);
self
}
#[must_use]
pub const fn new(label: String, value: String) -> Self {
Self {
default: false,
description: None,
emoji: None,
label,
value,
}
}
#[must_use]
pub fn unicode_emoji(mut self, emoji: String) -> Self {
self.emoji = Some(EmojiReactionType::Unicode { name: emoji });
self
}
}
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct TextInputBuilder {
custom_id: String,
label: String,
max_length: Option<u16>,
min_length: Option<u16>,
placeholder: Option<String>,
required: bool,
style: TextInputStyle,
value: Option<String>,
}
impl TextInputBuilder {
#[must_use]
pub fn build(self) -> TextInput {
TextInput {
custom_id: self.custom_id,
label: self.label,
max_length: self.max_length,
min_length: self.min_length,
placeholder: self.placeholder,
required: Some(self.required),
style: self.style,
value: self.value,
}
}
#[must_use]
pub const fn max_length(mut self, max_length: u16) -> Self {
self.max_length = Some(max_length);
self
}
#[must_use]
pub const fn min_length(mut self, min_length: u16) -> Self {
self.min_length = Some(min_length);
self
}
#[must_use]
pub const fn new(label: String, custom_id: String) -> Self {
Self {
custom_id,
label,
max_length: None,
min_length: None,
placeholder: None,
required: false,
style: TextInputStyle::Short,
value: None,
}
}
#[must_use]
pub const fn paragraph(mut self) -> Self {
self.style = TextInputStyle::Paragraph;
self
}
#[must_use]
pub fn placeholder(mut self, placeholder: String) -> Self {
self.placeholder = Some(placeholder);
self
}
#[must_use]
pub const fn require(mut self) -> Self {
self.required = true;
self
}
#[must_use]
pub fn value(mut self, value: String) -> Self {
self.value = Some(value);
self
}
}