1use crate::Snowflake;
6use crate::TitanString;
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Deserialize, Serialize)]
11pub struct GuildMember<'a> {
12 #[serde(default)]
14 pub user: Option<super::User<'a>>,
15
16 #[serde(default)]
18 pub nick: Option<TitanString<'a>>,
19
20 #[serde(default)]
22 pub avatar: Option<TitanString<'a>>,
23
24 #[serde(default)]
26 pub roles: smallvec::SmallVec<[Snowflake; 8]>,
27
28 pub joined_at: TitanString<'a>,
30
31 #[serde(default)]
33 pub premium_since: Option<TitanString<'a>>,
34
35 #[serde(default)]
37 pub deaf: bool,
38
39 #[serde(default)]
41 pub mute: bool,
42
43 #[serde(default)]
45 pub flags: u64,
46
47 #[serde(default)]
49 pub pending: Option<bool>,
50
51 #[serde(default)]
53 pub permissions: Option<crate::permissions::Permissions>,
54
55 #[serde(default)]
57 pub communication_disabled_until: Option<TitanString<'a>>,
58}
59
60#[derive(Debug, Clone, Deserialize, Serialize)]
62pub struct Role<'a> {
63 pub id: Snowflake,
65
66 pub name: TitanString<'a>,
68
69 pub color: u32,
71
72 pub hoist: bool,
74
75 #[serde(default)]
77 pub icon: Option<TitanString<'a>>,
78
79 #[serde(default)]
81 pub unicode_emoji: Option<TitanString<'a>>,
82
83 pub position: i32,
85
86 pub permissions: crate::permissions::Permissions,
88
89 pub managed: bool,
91
92 pub mentionable: bool,
94
95 #[serde(default)]
97 pub tags: Option<RoleTags>,
98
99 #[serde(default)]
101 pub flags: u64,
102}
103
104#[derive(Debug, Clone, Deserialize, Serialize)]
106pub struct RoleTags {
107 #[serde(default)]
109 pub bot_id: Option<Snowflake>,
110
111 #[serde(default)]
113 pub integration_id: Option<Snowflake>,
114
115 #[serde(default)]
117 pub premium_subscriber: Option<()>,
118
119 #[serde(default)]
121 pub subscription_listing_id: Option<Snowflake>,
122
123 #[serde(default)]
125 pub available_for_purchase: Option<()>,
126
127 #[serde(default)]
129 pub guild_connections: Option<()>,
130}
131
132#[derive(Debug, Clone, Deserialize, Serialize)]
134pub struct Emoji<'a> {
135 #[serde(default)]
137 pub id: Option<Snowflake>,
138
139 #[serde(default)]
141 pub name: Option<TitanString<'a>>,
142
143 #[serde(default)]
145 pub roles: smallvec::SmallVec<[Snowflake; 8]>,
146
147 #[serde(default)]
149 pub user: Option<super::User<'a>>,
150
151 #[serde(default)]
153 pub require_colons: bool,
154
155 #[serde(default)]
157 pub managed: bool,
158
159 #[serde(default)]
161 pub animated: bool,
162
163 #[serde(default)]
165 pub available: bool,
166}
167
168impl Emoji<'_> {
169 #[must_use]
171 pub fn url(&self) -> Option<String> {
172 self.id.map(|id| {
173 let ext = if self.animated { "gif" } else { "png" };
174 format!("https://cdn.discordapp.com/emojis/{id}.{ext}")
175 })
176 }
177}
178
179#[derive(Debug, Clone, Deserialize, Serialize)]
181pub struct Sticker<'a> {
182 pub id: Snowflake,
184
185 #[serde(default)]
187 pub pack_id: Option<Snowflake>,
188
189 pub name: TitanString<'a>,
191
192 #[serde(default)]
194 pub description: Option<TitanString<'a>>,
195
196 #[serde(default)]
198 pub tags: TitanString<'a>,
199
200 #[serde(rename = "type")]
202 pub sticker_type: u8,
203
204 #[serde(rename = "format_type")]
206 pub format_type: u8,
207
208 #[serde(default)]
211 pub user: Option<super::User<'a>>,
212
213 #[serde(default)]
215 pub sort_value: Option<u32>,
216}
217
218impl Sticker<'_> {
219 #[must_use]
221 pub fn url(&self) -> String {
222 let ext = match self.format_type {
225 3 => "json", 4 => "gif", _ => "png", };
229 format!("https://cdn.discordapp.com/stickers/{}.{}", self.id, ext)
230 }
231}
232
233#[cfg(test)]
234mod tests {
235 use super::*;
236
237 #[test]
238 fn test_guild_member_deserialize() {
239 let json = r#"{
240 "nick": "Test Nick",
241 "roles": ["123456789"],
242 "joined_at": "2021-01-01T00:00:00.000Z",
243 "deaf": false,
244 "mute": false,
245 "flags": 0
246 }"#;
247
248 let member: GuildMember = crate::json::from_str(json).unwrap();
249 assert_eq!(member.nick, Some(TitanString::Borrowed("Test Nick")));
250 }
251
252 #[test]
253 fn test_role_deserialize() {
254 let json = r#"{
255 "id": "123",
256 "name": "Admin",
257 "color": 16711680,
258 "hoist": true,
259 "position": 10,
260 "permissions": "8",
261 "managed": false,
262 "mentionable": true,
263 "flags": 0
264 }"#;
265
266 let role: Role = crate::json::from_str(json).unwrap();
267 assert_eq!(role.name, "Admin");
268 assert_eq!(role.color, 16711680);
269 }
270}