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        Invite, InviteChannel, InviteGuild, InviteType, TargetType, User, WelcomeScreen,
54        welcome_screen::WelcomeScreenChannel,
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                primary_guild: None,
220                public_flags: None,
221                system: None,
222                verified: None,
223            }),
224            max_age: Some(86_400),
225            max_uses: Some(10),
226            target_type: Some(TargetType::Stream),
227            target_user: Some(User {
228                accent_color: None,
229                avatar: None,
230                avatar_decoration: None,
231                avatar_decoration_data: None,
232                banner: None,
233                bot: false,
234                discriminator: 1,
235                email: None,
236                flags: None,
237                global_name: Some("test".to_owned()),
238                id: Id::new(2),
239                locale: None,
240                mfa_enabled: None,
241                name: "test".to_owned(),
242                premium_type: None,
243                primary_guild: None,
244                public_flags: None,
245                system: None,
246                verified: None,
247            }),
248            temporary: Some(false),
249            kind: InviteType::Guild,
250            uses: Some(3),
251        };
252
253        serde_test::assert_tokens(
254            &value,
255            &[
256                Token::Struct {
257                    name: "Invite",
258                    len: 15,
259                },
260                Token::Str("approximate_member_count"),
261                Token::Some,
262                Token::U64(31),
263                Token::Str("approximate_presence_count"),
264                Token::Some,
265                Token::U64(7),
266                Token::Str("channel"),
267                Token::Some,
268                Token::Struct {
269                    name: "InviteChannel",
270                    len: 2,
271                },
272                Token::Str("id"),
273                Token::NewtypeStruct { name: "Id" },
274                Token::Str("2"),
275                Token::Str("type"),
276                Token::U8(3),
277                Token::StructEnd,
278                Token::Str("code"),
279                Token::Str("uniquecode"),
280                Token::Str("created_at"),
281                Token::Some,
282                Token::Str("2021-08-03T16:08:36.325000+00:00"),
283                Token::Str("expires_at"),
284                Token::Some,
285                Token::Str("2021-08-10T16:08:36.325000+00:00"),
286                Token::Str("guild"),
287                Token::Some,
288                Token::Struct {
289                    name: "InviteGuild",
290                    len: 11,
291                },
292                Token::Str("banner"),
293                Token::Some,
294                Token::Str(image_hash::BANNER_INPUT),
295                Token::Str("description"),
296                Token::Some,
297                Token::Str("a description"),
298                Token::Str("features"),
299                Token::Seq { len: Some(1) },
300                Token::Str("DISCOVERABLE"),
301                Token::SeqEnd,
302                Token::Str("icon"),
303                Token::Some,
304                Token::Str(image_hash::ICON_INPUT),
305                Token::Str("id"),
306                Token::NewtypeStruct { name: "Id" },
307                Token::Str("1"),
308                Token::Str("name"),
309                Token::Str("guild name"),
310                Token::Str("premium_subscription_count"),
311                Token::None,
312                Token::Str("splash"),
313                Token::Some,
314                Token::Str(image_hash::SPLASH_INPUT),
315                Token::Str("vanity_url_code"),
316                Token::Some,
317                Token::Str("twilight"),
318                Token::Str("verification_level"),
319                Token::U8(2),
320                Token::Str("welcome_screen"),
321                Token::Some,
322                Token::Struct {
323                    name: "WelcomeScreen",
324                    len: 2,
325                },
326                Token::Str("description"),
327                Token::Some,
328                Token::Str("welcome description"),
329                Token::Str("welcome_channels"),
330                Token::Seq { len: Some(2) },
331                Token::Struct {
332                    name: "WelcomeScreenChannel",
333                    len: 4,
334                },
335                Token::Str("channel_id"),
336                Token::NewtypeStruct { name: "Id" },
337                Token::Str("123"),
338                Token::Str("description"),
339                Token::Str("channel description"),
340                Token::Str("emoji_id"),
341                Token::None,
342                Token::Str("emoji_name"),
343                Token::Some,
344                Token::Str("\u{1f352}"),
345                Token::StructEnd,
346                Token::Struct {
347                    name: "WelcomeScreenChannel",
348                    len: 4,
349                },
350                Token::Str("channel_id"),
351                Token::NewtypeStruct { name: "Id" },
352                Token::Str("456"),
353                Token::Str("description"),
354                Token::Str("custom description"),
355                Token::Str("emoji_id"),
356                Token::Some,
357                Token::NewtypeStruct { name: "Id" },
358                Token::Str("789"),
359                Token::Str("emoji_name"),
360                Token::Some,
361                Token::Str("custom_name"),
362                Token::StructEnd,
363                Token::SeqEnd,
364                Token::StructEnd,
365                Token::StructEnd,
366                Token::Str("inviter"),
367                Token::Some,
368                Token::Struct {
369                    name: "User",
370                    len: 10,
371                },
372                Token::Str("accent_color"),
373                Token::None,
374                Token::Str("avatar"),
375                Token::None,
376                Token::Str("avatar_decoration"),
377                Token::None,
378                Token::Str("avatar_decoration_data"),
379                Token::None,
380                Token::Str("banner"),
381                Token::None,
382                Token::Str("bot"),
383                Token::Bool(false),
384                Token::Str("discriminator"),
385                Token::Str("0001"),
386                Token::Str("global_name"),
387                Token::Some,
388                Token::Str("test"),
389                Token::Str("id"),
390                Token::NewtypeStruct { name: "Id" },
391                Token::Str("2"),
392                Token::Str("username"),
393                Token::Str("test"),
394                Token::StructEnd,
395                Token::Str("max_age"),
396                Token::Some,
397                Token::U64(86_400),
398                Token::Str("max_uses"),
399                Token::Some,
400                Token::U64(10),
401                Token::Str("target_type"),
402                Token::Some,
403                Token::U8(1),
404                Token::Str("target_user"),
405                Token::Some,
406                Token::Struct {
407                    name: "User",
408                    len: 10,
409                },
410                Token::Str("accent_color"),
411                Token::None,
412                Token::Str("avatar"),
413                Token::None,
414                Token::Str("avatar_decoration"),
415                Token::None,
416                Token::Str("avatar_decoration_data"),
417                Token::None,
418                Token::Str("banner"),
419                Token::None,
420                Token::Str("bot"),
421                Token::Bool(false),
422                Token::Str("discriminator"),
423                Token::Str("0001"),
424                Token::Str("global_name"),
425                Token::Some,
426                Token::Str("test"),
427                Token::Str("id"),
428                Token::NewtypeStruct { name: "Id" },
429                Token::Str("2"),
430                Token::Str("username"),
431                Token::Str("test"),
432                Token::StructEnd,
433                Token::Str("temporary"),
434                Token::Some,
435                Token::Bool(false),
436                Token::Str("type"),
437                Token::U8(0),
438                Token::Str("uses"),
439                Token::Some,
440                Token::U64(3),
441                Token::StructEnd,
442            ],
443        );
444
445        Ok(())
446    }
447}