twilight_model/guild/onboarding/
option.rs

1use crate::{
2    guild::Emoji,
3    id::{
4        marker::{ChannelMarker, EmojiMarker, OnboardingPromptOptionMarker, RoleMarker},
5        Id,
6    },
7};
8use serde::{Deserialize, Serialize};
9
10/// An emoji for a guild onboarding prompt.
11/// This is used instead of [`Emoji`] as both it's id and name can be `null` in
12/// prompt options.
13///
14/// [`Emoji`]: crate::guild::Emoji
15#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
16pub struct OnboardingPromptEmoji {
17    pub name: Option<String>,
18    pub id: Option<Id<EmojiMarker>>,
19    #[serde(default)]
20    pub animated: bool,
21}
22
23impl From<Emoji> for OnboardingPromptEmoji {
24    fn from(value: Emoji) -> Self {
25        Self {
26            animated: value.animated,
27            id: Some(value.id),
28            name: Some(value.name),
29        }
30    }
31}
32
33/// A prompt option for a guild onboarding screen.
34#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
35pub struct OnboardingPromptOption {
36    /// Channels opted into when this option is selected.
37    pub channel_ids: Vec<Id<ChannelMarker>>,
38    /// Description of the option.
39    pub description: Option<String>,
40    /// Emoji of the option.
41    pub emoji: OnboardingPromptEmoji,
42    /// ID of the option.
43    pub id: Id<OnboardingPromptOptionMarker>,
44    /// Roles assigned when this option is selected.
45    pub role_ids: Vec<Id<RoleMarker>>,
46    /// Title of the option.
47    pub title: String,
48}
49
50#[cfg(test)]
51mod tests {
52    use super::{OnboardingPromptEmoji, OnboardingPromptOption};
53    use crate::{
54        guild::Emoji,
55        id::{
56            marker::{ChannelMarker, EmojiMarker, OnboardingPromptOptionMarker, RoleMarker},
57            Id,
58        },
59    };
60    use serde_test::Token;
61
62    #[test]
63    fn prompt_option() {
64        let option = OnboardingPromptOption {
65            channel_ids: Vec::from([
66                Id::<ChannelMarker>::new(1),
67                Id::<ChannelMarker>::new(2),
68                Id::<ChannelMarker>::new(3),
69            ]),
70            description: Some(String::from("an option description")),
71            emoji: OnboardingPromptEmoji {
72                animated: false,
73                id: Some(Id::<EmojiMarker>::new(7)),
74                name: Some(String::from("test")),
75            },
76            id: Id::<OnboardingPromptOptionMarker>::new(123_456_789),
77            role_ids: Vec::from([
78                Id::<RoleMarker>::new(4),
79                Id::<RoleMarker>::new(5),
80                Id::<RoleMarker>::new(6),
81            ]),
82            title: String::from("an option"),
83        };
84
85        serde_test::assert_tokens(
86            &option,
87            &[
88                Token::Struct {
89                    name: "OnboardingPromptOption",
90                    len: 6,
91                },
92                Token::Str("channel_ids"),
93                Token::Seq { len: Some(3) },
94                Token::NewtypeStruct { name: "Id" },
95                Token::Str("1"),
96                Token::NewtypeStruct { name: "Id" },
97                Token::Str("2"),
98                Token::NewtypeStruct { name: "Id" },
99                Token::Str("3"),
100                Token::SeqEnd,
101                Token::Str("description"),
102                Token::Some,
103                Token::Str("an option description"),
104                Token::Str("emoji"),
105                Token::Struct {
106                    name: "OnboardingPromptEmoji",
107                    len: 3,
108                },
109                Token::Str("name"),
110                Token::Some,
111                Token::Str("test"),
112                Token::Str("id"),
113                Token::Some,
114                Token::NewtypeStruct { name: "Id" },
115                Token::Str("7"),
116                Token::Str("animated"),
117                Token::Bool(false),
118                Token::StructEnd,
119                Token::Str("id"),
120                Token::NewtypeStruct { name: "Id" },
121                Token::Str("123456789"),
122                Token::Str("role_ids"),
123                Token::Seq { len: Some(3) },
124                Token::NewtypeStruct { name: "Id" },
125                Token::Str("4"),
126                Token::NewtypeStruct { name: "Id" },
127                Token::Str("5"),
128                Token::NewtypeStruct { name: "Id" },
129                Token::Str("6"),
130                Token::SeqEnd,
131                Token::Str("title"),
132                Token::Str("an option"),
133                Token::StructEnd,
134            ],
135        )
136    }
137
138    #[test]
139    fn conversion() {
140        let emoji = Emoji {
141            animated: false,
142            available: false,
143            id: Id::<EmojiMarker>::new(7),
144            managed: false,
145            name: String::from("test"),
146            require_colons: false,
147            roles: Vec::new(),
148            user: None,
149        };
150
151        let emoji: OnboardingPromptEmoji = emoji.into();
152
153        assert!(!emoji.animated);
154        assert_eq!(emoji.id, Some(Id::<EmojiMarker>::new(7)));
155        assert_eq!(emoji.name, Some(String::from("test")));
156    }
157}