1mod channel;
2mod guild;
3mod kind;
4
5pub use self::{channel::WebhookChannel, guild::WebhookGuild, kind::WebhookType};
6
7use crate::{
8 id::{
9 marker::{ApplicationMarker, ChannelMarker, GuildMarker, WebhookMarker},
10 Id,
11 },
12 user::User,
13 util::image_hash::ImageHash,
14};
15use serde::{Deserialize, Serialize};
16
17#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
18pub struct Webhook {
19 #[serde(skip_serializing_if = "Option::is_none")]
20 pub application_id: Option<Id<ApplicationMarker>>,
21 pub avatar: Option<ImageHash>,
22 pub channel_id: Id<ChannelMarker>,
23 #[serde(skip_serializing_if = "Option::is_none")]
24 pub guild_id: Option<Id<GuildMarker>>,
25 pub id: Id<WebhookMarker>,
26 #[serde(default = "WebhookType::default", rename = "type")]
27 pub kind: WebhookType,
28 pub name: Option<String>,
29 #[serde(skip_serializing_if = "Option::is_none")]
31 pub source_channel: Option<WebhookChannel>,
32 #[serde(skip_serializing_if = "Option::is_none")]
34 pub source_guild: Option<WebhookGuild>,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 pub token: Option<String>,
37 #[serde(skip_serializing_if = "Option::is_none")]
43 pub url: Option<String>,
44 #[serde(skip_serializing_if = "Option::is_none")]
45 pub user: Option<User>,
46}
47
48#[cfg(test)]
49mod tests {
50 use super::{User, Webhook, WebhookChannel, WebhookGuild, WebhookType};
51 use crate::{id::Id, test::image_hash};
52 use serde::{Deserialize, Serialize};
53 use serde_test::Token;
54 use static_assertions::{assert_fields, assert_impl_all};
55 use std::{fmt::Debug, hash::Hash};
56
57 assert_fields!(
58 Webhook: application_id,
59 avatar,
60 channel_id,
61 guild_id,
62 id,
63 kind,
64 name,
65 source_channel,
66 source_guild,
67 token,
68 user
69 );
70
71 assert_impl_all!(
72 Webhook: Clone,
73 Debug,
74 Deserialize<'static>,
75 Eq,
76 Hash,
77 PartialEq,
78 Serialize
79 );
80
81 #[test]
82 fn webhook() {
83 let value = Webhook {
84 application_id: Some(Id::new(4)),
85 avatar: Some(image_hash::AVATAR),
86 channel_id: Id::new(1),
87 guild_id: Some(Id::new(2)),
88 id: Id::new(3),
89 kind: WebhookType::Incoming,
90 name: Some("a webhook".to_owned()),
91 source_channel: None,
92 source_guild: None,
93 token: Some("a token".to_owned()),
94 url: None,
95 user: None,
96 };
97
98 serde_test::assert_tokens(
99 &value,
100 &[
101 Token::Struct {
102 name: "Webhook",
103 len: 8,
104 },
105 Token::Str("application_id"),
106 Token::Some,
107 Token::NewtypeStruct { name: "Id" },
108 Token::Str("4"),
109 Token::Str("avatar"),
110 Token::Some,
111 Token::Str(image_hash::AVATAR_INPUT),
112 Token::Str("channel_id"),
113 Token::NewtypeStruct { name: "Id" },
114 Token::Str("1"),
115 Token::Str("guild_id"),
116 Token::Some,
117 Token::NewtypeStruct { name: "Id" },
118 Token::Str("2"),
119 Token::Str("id"),
120 Token::NewtypeStruct { name: "Id" },
121 Token::Str("3"),
122 Token::Str("type"),
123 Token::U8(1),
124 Token::Str("name"),
125 Token::Some,
126 Token::Str("a webhook"),
127 Token::Str("token"),
128 Token::Some,
129 Token::Str("a token"),
130 Token::StructEnd,
131 ],
132 );
133 }
134
135 #[allow(clippy::too_many_lines)]
136 #[test]
137 fn webhook_complete() {
138 let value = Webhook {
139 application_id: Some(Id::new(4)),
140 avatar: Some(image_hash::AVATAR),
141 channel_id: Id::new(1),
142 guild_id: Some(Id::new(2)),
143 id: Id::new(3),
144 kind: WebhookType::Incoming,
145 name: Some("a webhook".to_owned()),
146 source_channel: Some(WebhookChannel {
147 id: Id::new(4),
148 name: "webhook channel".into(),
149 }),
150 source_guild: Some(WebhookGuild {
151 icon: Some(image_hash::ICON),
152 id: Id::new(5),
153 name: "webhook guild".into(),
154 }),
155 token: Some("a token".to_owned()),
156 url: Some("https://a-url".to_owned()),
157 user: Some(User {
158 accent_color: None,
159 avatar: None,
160 avatar_decoration: None,
161 avatar_decoration_data: None,
162 banner: None,
163 bot: false,
164 discriminator: 1,
165 email: None,
166 flags: None,
167 global_name: Some("test".to_owned()),
168 id: Id::new(2),
169 locale: None,
170 mfa_enabled: None,
171 name: "test".to_owned(),
172 premium_type: None,
173 public_flags: None,
174 system: None,
175 verified: None,
176 }),
177 };
178
179 serde_test::assert_tokens(
180 &value,
181 &[
182 Token::Struct {
183 name: "Webhook",
184 len: 12,
185 },
186 Token::Str("application_id"),
187 Token::Some,
188 Token::NewtypeStruct { name: "Id" },
189 Token::Str("4"),
190 Token::Str("avatar"),
191 Token::Some,
192 Token::Str(image_hash::AVATAR_INPUT),
193 Token::Str("channel_id"),
194 Token::NewtypeStruct { name: "Id" },
195 Token::Str("1"),
196 Token::Str("guild_id"),
197 Token::Some,
198 Token::NewtypeStruct { name: "Id" },
199 Token::Str("2"),
200 Token::Str("id"),
201 Token::NewtypeStruct { name: "Id" },
202 Token::Str("3"),
203 Token::Str("type"),
204 Token::U8(1),
205 Token::Str("name"),
206 Token::Some,
207 Token::Str("a webhook"),
208 Token::Str("source_channel"),
209 Token::Some,
210 Token::Struct {
211 name: "WebhookChannel",
212 len: 2,
213 },
214 Token::Str("id"),
215 Token::NewtypeStruct { name: "Id" },
216 Token::Str("4"),
217 Token::Str("name"),
218 Token::Str("webhook channel"),
219 Token::StructEnd,
220 Token::Str("source_guild"),
221 Token::Some,
222 Token::Struct {
223 name: "WebhookGuild",
224 len: 3,
225 },
226 Token::Str("icon"),
227 Token::Some,
228 Token::Str(image_hash::ICON_INPUT),
229 Token::Str("id"),
230 Token::NewtypeStruct { name: "Id" },
231 Token::Str("5"),
232 Token::Str("name"),
233 Token::Str("webhook guild"),
234 Token::StructEnd,
235 Token::Str("token"),
236 Token::Some,
237 Token::Str("a token"),
238 Token::Str("url"),
239 Token::Some,
240 Token::Str("https://a-url"),
241 Token::Str("user"),
242 Token::Some,
243 Token::Struct {
244 name: "User",
245 len: 10,
246 },
247 Token::Str("accent_color"),
248 Token::None,
249 Token::Str("avatar"),
250 Token::None,
251 Token::Str("avatar_decoration"),
252 Token::None,
253 Token::Str("avatar_decoration_data"),
254 Token::None,
255 Token::Str("banner"),
256 Token::None,
257 Token::Str("bot"),
258 Token::Bool(false),
259 Token::Str("discriminator"),
260 Token::Str("0001"),
261 Token::Str("global_name"),
262 Token::Some,
263 Token::Str("test"),
264 Token::Str("id"),
265 Token::NewtypeStruct { name: "Id" },
266 Token::Str("2"),
267 Token::Str("username"),
268 Token::Str("test"),
269 Token::StructEnd,
270 Token::StructEnd,
271 ],
272 );
273 }
274}