twilight_model/gateway/payload/incoming/
typing_start.rs

1use crate::{
2    guild::Member,
3    id::{
4        Id,
5        marker::{ChannelMarker, GuildMarker, UserMarker},
6    },
7};
8use serde::{Deserialize, Serialize};
9
10#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
11pub struct TypingStart {
12    pub channel_id: Id<ChannelMarker>,
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub guild_id: Option<Id<GuildMarker>>,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub member: Option<Member>,
17    pub timestamp: u64,
18    pub user_id: Id<UserMarker>,
19}
20
21#[cfg(test)]
22mod tests {
23    use super::TypingStart;
24    use crate::{
25        guild::{Member, MemberFlags},
26        id::Id,
27        test::image_hash,
28        user::User,
29        util::datetime::{Timestamp, TimestampParseError},
30    };
31    use serde_test::Token;
32    use std::str::FromStr;
33
34    #[allow(clippy::too_many_lines)]
35    #[test]
36    fn typing_start_with_member() -> Result<(), TimestampParseError> {
37        let joined_at = Some(Timestamp::from_str("2020-01-01T00:00:00.000000+00:00")?);
38        let flags = MemberFlags::BYPASSES_VERIFICATION | MemberFlags::DID_REJOIN;
39
40        let value = TypingStart {
41            channel_id: Id::new(2),
42            guild_id: Some(Id::new(1)),
43            member: Some(Member {
44                avatar: None,
45                avatar_decoration_data: None,
46                banner: None,
47                communication_disabled_until: None,
48                deaf: false,
49                flags,
50                joined_at,
51                mute: false,
52                nick: Some("typing".to_owned()),
53                pending: false,
54                premium_since: None,
55                roles: vec![Id::new(4)],
56                user: User {
57                    id: Id::new(3),
58                    accent_color: None,
59                    avatar: Some(image_hash::AVATAR),
60                    avatar_decoration: None,
61                    avatar_decoration_data: None,
62                    banner: None,
63                    bot: false,
64                    discriminator: 1,
65                    global_name: Some("test".to_owned()),
66                    name: "test".to_owned(),
67                    mfa_enabled: None,
68                    locale: None,
69                    verified: None,
70                    email: None,
71                    flags: None,
72                    premium_type: None,
73                    primary_guild: None,
74                    public_flags: None,
75                    system: None,
76                },
77            }),
78            timestamp: 1_500_000_000,
79            user_id: Id::new(3),
80        };
81
82        serde_test::assert_tokens(
83            &value,
84            &[
85                Token::Struct {
86                    name: "TypingStart",
87                    len: 5,
88                },
89                Token::Str("channel_id"),
90                Token::NewtypeStruct { name: "Id" },
91                Token::Str("2"),
92                Token::Str("guild_id"),
93                Token::Some,
94                Token::NewtypeStruct { name: "Id" },
95                Token::Str("1"),
96                Token::Str("member"),
97                Token::Some,
98                Token::Struct {
99                    name: "Member",
100                    len: 9,
101                },
102                Token::Str("communication_disabled_until"),
103                Token::None,
104                Token::Str("deaf"),
105                Token::Bool(false),
106                Token::Str("flags"),
107                Token::U64(flags.bits()),
108                Token::Str("joined_at"),
109                Token::Some,
110                Token::Str("2020-01-01T00:00:00.000000+00:00"),
111                Token::Str("mute"),
112                Token::Bool(false),
113                Token::Str("nick"),
114                Token::Some,
115                Token::Str("typing"),
116                Token::Str("pending"),
117                Token::Bool(false),
118                Token::Str("roles"),
119                Token::Seq { len: Some(1) },
120                Token::NewtypeStruct { name: "Id" },
121                Token::Str("4"),
122                Token::SeqEnd,
123                Token::Str("user"),
124                Token::Struct {
125                    name: "User",
126                    len: 10,
127                },
128                Token::Str("accent_color"),
129                Token::None,
130                Token::Str("avatar"),
131                Token::Some,
132                Token::Str(image_hash::AVATAR_INPUT),
133                Token::Str("avatar_decoration"),
134                Token::None,
135                Token::Str("avatar_decoration_data"),
136                Token::None,
137                Token::Str("banner"),
138                Token::None,
139                Token::Str("bot"),
140                Token::Bool(false),
141                Token::Str("discriminator"),
142                Token::Str("0001"),
143                Token::Str("global_name"),
144                Token::Some,
145                Token::Str("test"),
146                Token::Str("id"),
147                Token::NewtypeStruct { name: "Id" },
148                Token::Str("3"),
149                Token::Str("username"),
150                Token::Str("test"),
151                Token::StructEnd,
152                Token::StructEnd,
153                Token::Str("timestamp"),
154                Token::U64(1_500_000_000),
155                Token::Str("user_id"),
156                Token::NewtypeStruct { name: "Id" },
157                Token::Str("3"),
158                Token::StructEnd,
159            ],
160        );
161
162        Ok(())
163    }
164
165    #[test]
166    fn typing_start_without_member() {
167        let value = TypingStart {
168            channel_id: Id::new(2),
169            guild_id: None,
170            member: None,
171            timestamp: 1_500_000_000,
172            user_id: Id::new(3),
173        };
174
175        serde_test::assert_tokens(
176            &value,
177            &[
178                Token::Struct {
179                    name: "TypingStart",
180                    len: 3,
181                },
182                Token::Str("channel_id"),
183                Token::NewtypeStruct { name: "Id" },
184                Token::Str("2"),
185                Token::Str("timestamp"),
186                Token::U64(1_500_000_000),
187                Token::Str("user_id"),
188                Token::NewtypeStruct { name: "Id" },
189                Token::Str("3"),
190                Token::StructEnd,
191            ],
192        );
193    }
194}