twilight_model/gateway/payload/incoming/
typing_start.rs1use crate::{
2 guild::Member,
3 id::{
4 marker::{ChannelMarker, GuildMarker, UserMarker},
5 Id,
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 communication_disabled_until: None,
46 deaf: false,
47 flags,
48 joined_at,
49 mute: false,
50 nick: Some("typing".to_owned()),
51 pending: false,
52 premium_since: None,
53 roles: vec![Id::new(4)],
54 user: User {
55 id: Id::new(3),
56 accent_color: None,
57 avatar: Some(image_hash::AVATAR),
58 avatar_decoration: None,
59 avatar_decoration_data: None,
60 banner: None,
61 bot: false,
62 discriminator: 1,
63 global_name: Some("test".to_owned()),
64 name: "test".to_owned(),
65 mfa_enabled: None,
66 locale: None,
67 verified: None,
68 email: None,
69 flags: None,
70 premium_type: None,
71 system: None,
72 public_flags: None,
73 },
74 }),
75 timestamp: 1_500_000_000,
76 user_id: Id::new(3),
77 };
78
79 serde_test::assert_tokens(
80 &value,
81 &[
82 Token::Struct {
83 name: "TypingStart",
84 len: 5,
85 },
86 Token::Str("channel_id"),
87 Token::NewtypeStruct { name: "Id" },
88 Token::Str("2"),
89 Token::Str("guild_id"),
90 Token::Some,
91 Token::NewtypeStruct { name: "Id" },
92 Token::Str("1"),
93 Token::Str("member"),
94 Token::Some,
95 Token::Struct {
96 name: "Member",
97 len: 9,
98 },
99 Token::Str("communication_disabled_until"),
100 Token::None,
101 Token::Str("deaf"),
102 Token::Bool(false),
103 Token::Str("flags"),
104 Token::U64(flags.bits()),
105 Token::Str("joined_at"),
106 Token::Some,
107 Token::Str("2020-01-01T00:00:00.000000+00:00"),
108 Token::Str("mute"),
109 Token::Bool(false),
110 Token::Str("nick"),
111 Token::Some,
112 Token::Str("typing"),
113 Token::Str("pending"),
114 Token::Bool(false),
115 Token::Str("roles"),
116 Token::Seq { len: Some(1) },
117 Token::NewtypeStruct { name: "Id" },
118 Token::Str("4"),
119 Token::SeqEnd,
120 Token::Str("user"),
121 Token::Struct {
122 name: "User",
123 len: 10,
124 },
125 Token::Str("accent_color"),
126 Token::None,
127 Token::Str("avatar"),
128 Token::Some,
129 Token::Str(image_hash::AVATAR_INPUT),
130 Token::Str("avatar_decoration"),
131 Token::None,
132 Token::Str("avatar_decoration_data"),
133 Token::None,
134 Token::Str("banner"),
135 Token::None,
136 Token::Str("bot"),
137 Token::Bool(false),
138 Token::Str("discriminator"),
139 Token::Str("0001"),
140 Token::Str("global_name"),
141 Token::Some,
142 Token::Str("test"),
143 Token::Str("id"),
144 Token::NewtypeStruct { name: "Id" },
145 Token::Str("3"),
146 Token::Str("username"),
147 Token::Str("test"),
148 Token::StructEnd,
149 Token::StructEnd,
150 Token::Str("timestamp"),
151 Token::U64(1_500_000_000),
152 Token::Str("user_id"),
153 Token::NewtypeStruct { name: "Id" },
154 Token::Str("3"),
155 Token::StructEnd,
156 ],
157 );
158
159 Ok(())
160 }
161
162 #[test]
163 fn typing_start_without_member() {
164 let value = TypingStart {
165 channel_id: Id::new(2),
166 guild_id: None,
167 member: None,
168 timestamp: 1_500_000_000,
169 user_id: Id::new(3),
170 };
171
172 serde_test::assert_tokens(
173 &value,
174 &[
175 Token::Struct {
176 name: "TypingStart",
177 len: 3,
178 },
179 Token::Str("channel_id"),
180 Token::NewtypeStruct { name: "Id" },
181 Token::Str("2"),
182 Token::Str("timestamp"),
183 Token::U64(1_500_000_000),
184 Token::Str("user_id"),
185 Token::NewtypeStruct { name: "Id" },
186 Token::Str("3"),
187 Token::StructEnd,
188 ],
189 );
190 }
191}