Skip to main content

twilight_model/channel/message/component/
select_menu.rs

1use crate::channel::{ChannelType, message::EmojiReactionType};
2use crate::id::Id;
3use crate::id::marker::{ChannelMarker, RoleMarker, UserMarker};
4use serde::{Deserialize, Serialize};
5
6/// Dropdown-style [`Component`] that renders below messages.
7///
8/// [`Component`]: super::Component
9#[derive(Clone, Debug, Eq, Hash, PartialEq)]
10pub struct SelectMenu {
11    /// An optional list of channel types.
12    ///
13    /// This is only applicable to [channel select menus](SelectMenuType::Channel).
14    pub channel_types: Option<Vec<ChannelType>>,
15    /// Developer defined identifier.
16    pub custom_id: String,
17    /// List of default values for auto-populated select menus.
18    pub default_values: Option<Vec<SelectDefaultValue>>,
19    /// Whether the select menu is disabled.
20    ///
21    /// Defaults to `false`.
22    pub disabled: bool,
23    /// Optional identifier for this select menu.
24    pub id: Option<i32>,
25    /// This select menu's type.
26    pub kind: SelectMenuType,
27    /// Maximum number of options that may be chosen.
28    pub max_values: Option<u8>,
29    /// Minimum number of options that must be chosen.
30    pub min_values: Option<u8>,
31    /// A list of available options.
32    ///
33    /// This is required by [text select menus](SelectMenuType::Text).
34    pub options: Option<Vec<SelectMenuOption>>,
35    /// Custom placeholder text if no option is selected.
36    pub placeholder: Option<String>,
37    /// Whether a selection is required in a modal.
38    ///
39    /// Ignored in messages.
40    pub required: Option<bool>,
41}
42
43/// A [`SelectMenu`]'s type.
44#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
45#[non_exhaustive]
46pub enum SelectMenuType {
47    /// Channel select menus.
48    Channel,
49    /// Mentionable select menus.
50    Mentionable,
51    /// Role select menus.
52    Role,
53    /// Select menus with a text-based `options` list.
54    ///
55    /// Select menus of this `kind` *must* set the `options` field to specify the options users
56    /// can pick from.
57    Text,
58    /// User select menus.
59    User,
60}
61
62/// Dropdown options that are part of [`SelectMenu`].
63#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
64pub struct SelectMenuOption {
65    /// Whether the option will be selected by default.
66    #[serde(default)]
67    pub default: bool,
68    /// Additional description.
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub description: Option<String>,
71    /// Emoji associated with the option. Appears left of the label and
72    /// description.
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub emoji: Option<EmojiReactionType>,
75    /// User-facing name.
76    pub label: String,
77    /// Developer defined value.
78    pub value: String,
79}
80
81/// A default value for an auto-populated select menu.
82#[derive(Copy, Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
83#[serde(tag = "type", content = "id", rename_all = "snake_case")]
84pub enum SelectDefaultValue {
85    /// Default channel.
86    Channel(Id<ChannelMarker>),
87    /// Default role.
88    Role(Id<RoleMarker>),
89    /// Default user.
90    User(Id<UserMarker>),
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96    use static_assertions::{assert_fields, assert_impl_all};
97    use std::{fmt::Debug, hash::Hash};
98
99    assert_fields!(
100        SelectMenu: channel_types,
101        custom_id,
102        default_values,
103        disabled,
104        id,
105        kind,
106        max_values,
107        min_values,
108        options,
109        placeholder,
110        required
111    );
112    assert_impl_all!(SelectMenu: Clone, Debug, Eq, Hash, PartialEq, Send, Sync);
113
114    assert_impl_all!(
115        SelectMenuType: Clone,
116        Debug,
117        Eq,
118        Hash,
119        PartialEq,
120        Send,
121        Sync
122    );
123
124    assert_impl_all!(
125        SelectMenuOption: Clone,
126        Debug,
127        Deserialize<'static>,
128        Eq,
129        Hash,
130        PartialEq,
131        Send,
132        Serialize,
133        Sync
134    );
135    assert_fields!(SelectMenuOption: default, description, emoji, label, value);
136
137    assert_impl_all!(
138        SelectDefaultValue: Copy,
139        Clone,
140        Debug,
141        Deserialize<'static>,
142        Eq,
143        Hash,
144        Ord,
145        PartialEq,
146        PartialOrd,
147        Serialize
148    );
149}