twilight_model/guild/invite/
mod.rs

1mod channel;
2mod guild;
3mod invite_type;
4mod target_type;
5mod welcome_screen;
6
7pub use self::{
8    channel::InviteChannel,
9    guild::InviteGuild,
10    invite_type::InviteType,
11    target_type::TargetType,
12    welcome_screen::{WelcomeScreen, WelcomeScreenChannel},
13};
14
15use crate::{user::User, util::Timestamp};
16use serde::{Deserialize, Serialize};
17
18#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
19pub struct Invite {
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub approximate_member_count: Option<u64>,
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub approximate_presence_count: Option<u64>,
24    pub channel: Option<InviteChannel>,
25    pub code: String,
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub created_at: Option<Timestamp>,
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub expires_at: Option<Timestamp>,
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub guild: Option<InviteGuild>,
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub inviter: Option<User>,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub max_age: Option<u64>,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub max_uses: Option<u64>,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub target_type: Option<TargetType>,
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub target_user: Option<User>,
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub temporary: Option<bool>,
44    #[serde(rename = "type")]
45    pub kind: InviteType,
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub uses: Option<u64>,
48}
49
50#[cfg(test)]
51mod tests {
52    use super::{
53        welcome_screen::WelcomeScreenChannel, Invite, InviteChannel, InviteGuild, InviteType,
54        TargetType, User, WelcomeScreen,
55    };
56    use crate::{
57        channel::ChannelType,
58        guild::{GuildFeature, VerificationLevel},
59        id::Id,
60        test::image_hash,
61        util::datetime::{Timestamp, TimestampParseError},
62    };
63    use serde::{Deserialize, Serialize};
64    use serde_test::Token;
65    use static_assertions::{assert_fields, assert_impl_all};
66    use std::{fmt::Debug, str::FromStr};
67
68    assert_fields!(
69        Invite: approximate_member_count,
70        approximate_presence_count,
71        channel,
72        code,
73        created_at,
74        expires_at,
75        guild,
76        inviter,
77        max_age,
78        max_uses,
79        target_type,
80        target_user,
81        temporary,
82        uses
83    );
84
85    assert_impl_all!(
86        Invite: Clone,
87        Debug,
88        Deserialize<'static>,
89        Eq,
90        PartialEq,
91        Serialize,
92        Send,
93        Sync,
94    );
95
96    #[test]
97    fn invite() {
98        let value = Invite {
99            approximate_member_count: Some(31),
100            approximate_presence_count: Some(7),
101            channel: Some(InviteChannel {
102                id: Id::new(2),
103                kind: ChannelType::Group,
104                name: None,
105            }),
106            code: "uniquecode".to_owned(),
107            created_at: None,
108            expires_at: None,
109            guild: None,
110            inviter: None,
111            max_age: None,
112            max_uses: None,
113            target_type: Some(TargetType::Stream),
114            target_user: None,
115            temporary: None,
116            kind: InviteType::Guild,
117            uses: None,
118        };
119
120        serde_test::assert_tokens(
121            &value,
122            &[
123                Token::Struct {
124                    name: "Invite",
125                    len: 6,
126                },
127                Token::Str("approximate_member_count"),
128                Token::Some,
129                Token::U64(31),
130                Token::Str("approximate_presence_count"),
131                Token::Some,
132                Token::U64(7),
133                Token::Str("channel"),
134                Token::Some,
135                Token::Struct {
136                    name: "InviteChannel",
137                    len: 2,
138                },
139                Token::Str("id"),
140                Token::NewtypeStruct { name: "Id" },
141                Token::Str("2"),
142                Token::Str("type"),
143                Token::U8(3),
144                Token::StructEnd,
145                Token::Str("code"),
146                Token::Str("uniquecode"),
147                Token::Str("target_type"),
148                Token::Some,
149                Token::U8(1),
150                Token::Str("type"),
151                Token::U8(0),
152                Token::StructEnd,
153            ],
154        );
155    }
156
157    #[allow(clippy::too_many_lines)]
158    #[test]
159    fn invite_complete() -> Result<(), TimestampParseError> {
160        let created_at = Timestamp::from_str("2021-08-03T16:08:36.325000+00:00")?;
161        let expires_at = Timestamp::from_str("2021-08-10T16:08:36.325000+00:00")?;
162
163        let value = Invite {
164            approximate_member_count: Some(31),
165            approximate_presence_count: Some(7),
166            channel: Some(InviteChannel {
167                id: Id::new(2),
168                kind: ChannelType::Group,
169                name: None,
170            }),
171            code: "uniquecode".to_owned(),
172            created_at: Some(created_at),
173            expires_at: Some(expires_at),
174            guild: Some(InviteGuild {
175                banner: Some(image_hash::BANNER),
176                description: Some("a description".to_owned()),
177                features: Vec::from([GuildFeature::Discoverable]),
178                icon: Some(image_hash::ICON),
179                id: Id::new(1),
180                name: "guild name".to_owned(),
181                premium_subscription_count: None,
182                splash: Some(image_hash::SPLASH),
183                vanity_url_code: Some("twilight".to_owned()),
184                verification_level: VerificationLevel::Medium,
185                welcome_screen: Some(WelcomeScreen {
186                    description: Some("welcome description".to_owned()),
187                    welcome_channels: vec![
188                        WelcomeScreenChannel {
189                            channel_id: Id::new(123),
190                            description: "channel description".to_owned(),
191                            emoji_id: None,
192                            emoji_name: Some("\u{1f352}".to_owned()),
193                        },
194                        WelcomeScreenChannel {
195                            channel_id: Id::new(456),
196                            description: "custom description".to_owned(),
197                            emoji_id: Some(Id::new(789)),
198                            emoji_name: Some("custom_name".to_owned()),
199                        },
200                    ],
201                }),
202            }),
203            inviter: Some(User {
204                accent_color: None,
205                avatar: None,
206                avatar_decoration: None,
207                avatar_decoration_data: None,
208                banner: None,
209                bot: false,
210                discriminator: 1,
211                email: None,
212                flags: None,
213                global_name: Some("test".to_owned()),
214                id: Id::new(2),
215                locale: None,
216                mfa_enabled: None,
217                name: "test".to_owned(),
218                premium_type: None,
219                public_flags: None,
220                system: None,
221                verified: None,
222            }),
223            max_age: Some(86_400),
224            max_uses: Some(10),
225            target_type: Some(TargetType::Stream),
226            target_user: Some(User {
227                accent_color: None,
228                avatar: None,
229                avatar_decoration: None,
230                avatar_decoration_data: None,
231                banner: None,
232                bot: false,
233                discriminator: 1,
234                email: None,
235                flags: None,
236                global_name: Some("test".to_owned()),
237                id: Id::new(2),
238                locale: None,
239                mfa_enabled: None,
240                name: "test".to_owned(),
241                premium_type: None,
242                public_flags: None,
243                system: None,
244                verified: None,
245            }),
246            temporary: Some(false),
247            kind: InviteType::Guild,
248            uses: Some(3),
249        };
250
251        serde_test::assert_tokens(
252            &value,
253            &[
254                Token::Struct {
255                    name: "Invite",
256                    len: 15,
257                },
258                Token::Str("approximate_member_count"),
259                Token::Some,
260                Token::U64(31),
261                Token::Str("approximate_presence_count"),
262                Token::Some,
263                Token::U64(7),
264                Token::Str("channel"),
265                Token::Some,
266                Token::Struct {
267                    name: "InviteChannel",
268                    len: 2,
269                },
270                Token::Str("id"),
271                Token::NewtypeStruct { name: "Id" },
272                Token::Str("2"),
273                Token::Str("type"),
274                Token::U8(3),
275                Token::StructEnd,
276                Token::Str("code"),
277                Token::Str("uniquecode"),
278                Token::Str("created_at"),
279                Token::Some,
280                Token::Str("2021-08-03T16:08:36.325000+00:00"),
281                Token::Str("expires_at"),
282                Token::Some,
283                Token::Str("2021-08-10T16:08:36.325000+00:00"),
284                Token::Str("guild"),
285                Token::Some,
286                Token::Struct {
287                    name: "InviteGuild",
288                    len: 11,
289                },
290                Token::Str("banner"),
291                Token::Some,
292                Token::Str(image_hash::BANNER_INPUT),
293                Token::Str("description"),
294                Token::Some,
295                Token::Str("a description"),
296                Token::Str("features"),
297                Token::Seq { len: Some(1) },
298                Token::Str("DISCOVERABLE"),
299                Token::SeqEnd,
300                Token::Str("icon"),
301                Token::Some,
302                Token::Str(image_hash::ICON_INPUT),
303                Token::Str("id"),
304                Token::NewtypeStruct { name: "Id" },
305                Token::Str("1"),
306                Token::Str("name"),
307                Token::Str("guild name"),
308                Token::Str("premium_subscription_count"),
309                Token::None,
310                Token::Str("splash"),
311                Token::Some,
312                Token::Str(image_hash::SPLASH_INPUT),
313                Token::Str("vanity_url_code"),
314                Token::Some,
315                Token::Str("twilight"),
316                Token::Str("verification_level"),
317                Token::U8(2),
318                Token::Str("welcome_screen"),
319                Token::Some,
320                Token::Struct {
321                    name: "WelcomeScreen",
322                    len: 2,
323                },
324                Token::Str("description"),
325                Token::Some,
326                Token::Str("welcome description"),
327                Token::Str("welcome_channels"),
328                Token::Seq { len: Some(2) },
329                Token::Struct {
330                    name: "WelcomeScreenChannel",
331                    len: 4,
332                },
333                Token::Str("channel_id"),
334                Token::NewtypeStruct { name: "Id" },
335                Token::Str("123"),
336                Token::Str("description"),
337                Token::Str("channel description"),
338                Token::Str("emoji_id"),
339                Token::None,
340                Token::Str("emoji_name"),
341                Token::Some,
342                Token::Str("\u{1f352}"),
343                Token::StructEnd,
344                Token::Struct {
345                    name: "WelcomeScreenChannel",
346                    len: 4,
347                },
348                Token::Str("channel_id"),
349                Token::NewtypeStruct { name: "Id" },
350                Token::Str("456"),
351                Token::Str("description"),
352                Token::Str("custom description"),
353                Token::Str("emoji_id"),
354                Token::Some,
355                Token::NewtypeStruct { name: "Id" },
356                Token::Str("789"),
357                Token::Str("emoji_name"),
358                Token::Some,
359                Token::Str("custom_name"),
360                Token::StructEnd,
361                Token::SeqEnd,
362                Token::StructEnd,
363                Token::StructEnd,
364                Token::Str("inviter"),
365                Token::Some,
366                Token::Struct {
367                    name: "User",
368                    len: 10,
369                },
370                Token::Str("accent_color"),
371                Token::None,
372                Token::Str("avatar"),
373                Token::None,
374                Token::Str("avatar_decoration"),
375                Token::None,
376                Token::Str("avatar_decoration_data"),
377                Token::None,
378                Token::Str("banner"),
379                Token::None,
380                Token::Str("bot"),
381                Token::Bool(false),
382                Token::Str("discriminator"),
383                Token::Str("0001"),
384                Token::Str("global_name"),
385                Token::Some,
386                Token::Str("test"),
387                Token::Str("id"),
388                Token::NewtypeStruct { name: "Id" },
389                Token::Str("2"),
390                Token::Str("username"),
391                Token::Str("test"),
392                Token::StructEnd,
393                Token::Str("max_age"),
394                Token::Some,
395                Token::U64(86_400),
396                Token::Str("max_uses"),
397                Token::Some,
398                Token::U64(10),
399                Token::Str("target_type"),
400                Token::Some,
401                Token::U8(1),
402                Token::Str("target_user"),
403                Token::Some,
404                Token::Struct {
405                    name: "User",
406                    len: 10,
407                },
408                Token::Str("accent_color"),
409                Token::None,
410                Token::Str("avatar"),
411                Token::None,
412                Token::Str("avatar_decoration"),
413                Token::None,
414                Token::Str("avatar_decoration_data"),
415                Token::None,
416                Token::Str("banner"),
417                Token::None,
418                Token::Str("bot"),
419                Token::Bool(false),
420                Token::Str("discriminator"),
421                Token::Str("0001"),
422                Token::Str("global_name"),
423                Token::Some,
424                Token::Str("test"),
425                Token::Str("id"),
426                Token::NewtypeStruct { name: "Id" },
427                Token::Str("2"),
428                Token::Str("username"),
429                Token::Str("test"),
430                Token::StructEnd,
431                Token::Str("temporary"),
432                Token::Some,
433                Token::Bool(false),
434                Token::Str("type"),
435                Token::U8(0),
436                Token::Str("uses"),
437                Token::Some,
438                Token::U64(3),
439                Token::StructEnd,
440            ],
441        );
442
443        Ok(())
444    }
445}