twilight_model/channel/message/component/
kind.rs

1use serde::{Deserialize, Serialize};
2use std::fmt::{Display, Formatter, Result as FmtResult};
3
4/// Type of [`Component`].
5///
6/// [`Component`]: super::Component
7#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
8#[non_exhaustive]
9#[serde(from = "u8", into = "u8")]
10pub enum ComponentType {
11    /// Component is an [`ActionRow`].
12    ///
13    /// [`ActionRow`]: super::ActionRow
14    ActionRow,
15    /// Component is an [`Button`].
16    ///
17    /// [`Button`]: super::Button
18    Button,
19    /// Component is a [`SelectMenu`] with custom string options.
20    ///
21    /// [`SelectMenu`]: super::SelectMenu
22    TextSelectMenu,
23    /// Component is an [`TextInput`].
24    ///
25    /// [`TextInput`]: super::TextInput
26    TextInput,
27    /// Component is a [`SelectMenu`] for users.
28    ///
29    /// [`SelectMenu`]: super::SelectMenu
30    UserSelectMenu,
31    /// Component is a [`SelectMenu`] for roles.
32    ///
33    /// [`SelectMenu`]: super::SelectMenu
34    RoleSelectMenu,
35    /// Component is a [`SelectMenu`] for mentionables.
36    ///
37    /// [`SelectMenu`]: super::SelectMenu
38    MentionableSelectMenu,
39    /// Component is a [`SelectMenu`] for channels.
40    ///
41    /// [`SelectMenu`]: super::SelectMenu
42    ChannelSelectMenu,
43    /// Variant value is unknown to the library.
44    Unknown(u8),
45}
46
47impl From<u8> for ComponentType {
48    fn from(value: u8) -> Self {
49        match value {
50            1 => ComponentType::ActionRow,
51            2 => ComponentType::Button,
52            3 => ComponentType::TextSelectMenu,
53            4 => ComponentType::TextInput,
54            5 => ComponentType::UserSelectMenu,
55            6 => ComponentType::RoleSelectMenu,
56            7 => ComponentType::MentionableSelectMenu,
57            8 => ComponentType::ChannelSelectMenu,
58            unknown => ComponentType::Unknown(unknown),
59        }
60    }
61}
62
63impl From<ComponentType> for u8 {
64    fn from(value: ComponentType) -> Self {
65        match value {
66            ComponentType::ActionRow => 1,
67            ComponentType::Button => 2,
68            ComponentType::TextSelectMenu => 3,
69            ComponentType::TextInput => 4,
70            ComponentType::UserSelectMenu => 5,
71            ComponentType::RoleSelectMenu => 6,
72            ComponentType::MentionableSelectMenu => 7,
73            ComponentType::ChannelSelectMenu => 8,
74            ComponentType::Unknown(unknown) => unknown,
75        }
76    }
77}
78
79impl ComponentType {
80    /// Name of the component type.
81    ///
82    /// Variants have a name equivalent to the variant name itself.
83    ///
84    /// # Examples
85    ///
86    /// Check the [`ActionRow`] variant's name:
87    ///
88    /// ```
89    /// use twilight_model::channel::message::component::ComponentType;
90    ///
91    /// assert_eq!("ActionRow", ComponentType::ActionRow.name());
92    /// ```
93    ///
94    /// [`ActionRow`]: Self::ActionRow
95    pub const fn name(self) -> &'static str {
96        match self {
97            Self::ActionRow => "ActionRow",
98            Self::Button => "Button",
99            Self::TextSelectMenu
100            | Self::UserSelectMenu
101            | Self::RoleSelectMenu
102            | Self::MentionableSelectMenu
103            | Self::ChannelSelectMenu => "SelectMenu",
104            Self::TextInput => "TextInput",
105            Self::Unknown(_) => "Unknown",
106        }
107    }
108}
109
110impl Display for ComponentType {
111    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
112        f.write_str(self.name())
113    }
114}
115
116#[cfg(test)]
117mod tests {
118    use super::*;
119    use serde_test::Token;
120    use static_assertions::assert_impl_all;
121    use std::{fmt::Debug, hash::Hash};
122
123    assert_impl_all!(
124        ComponentType: Clone,
125        Copy,
126        Debug,
127        Deserialize<'static>,
128        Eq,
129        Hash,
130        PartialEq,
131        Send,
132        Serialize,
133        Sync
134    );
135
136    #[test]
137    fn variants() {
138        serde_test::assert_tokens(&ComponentType::ActionRow, &[Token::U8(1)]);
139        serde_test::assert_tokens(&ComponentType::Button, &[Token::U8(2)]);
140        serde_test::assert_tokens(&ComponentType::TextSelectMenu, &[Token::U8(3)]);
141        serde_test::assert_tokens(&ComponentType::TextInput, &[Token::U8(4)]);
142        serde_test::assert_tokens(&ComponentType::UserSelectMenu, &[Token::U8(5)]);
143        serde_test::assert_tokens(&ComponentType::RoleSelectMenu, &[Token::U8(6)]);
144        serde_test::assert_tokens(&ComponentType::MentionableSelectMenu, &[Token::U8(7)]);
145        serde_test::assert_tokens(&ComponentType::ChannelSelectMenu, &[Token::U8(8)]);
146        serde_test::assert_tokens(&ComponentType::Unknown(99), &[Token::U8(99)]);
147    }
148
149    #[test]
150    fn names() {
151        assert_eq!("ActionRow", ComponentType::ActionRow.name());
152        assert_eq!("Button", ComponentType::Button.name());
153        assert_eq!("SelectMenu", ComponentType::TextSelectMenu.name());
154        assert_eq!("SelectMenu", ComponentType::UserSelectMenu.name());
155        assert_eq!("SelectMenu", ComponentType::RoleSelectMenu.name());
156        assert_eq!("SelectMenu", ComponentType::MentionableSelectMenu.name());
157        assert_eq!("SelectMenu", ComponentType::ChannelSelectMenu.name());
158        assert_eq!("TextInput", ComponentType::TextInput.name());
159        assert_eq!("Unknown", ComponentType::Unknown(99).name());
160    }
161}