1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 autumn::Attachment,
7 channels::ChannelPermissions,
8 id::{CategoryId, ChannelId, MemberId, RoleId, ServerId, UserId},
9};
10
11pub type MemberCompositeKey = MemberId;
18
19#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
22#[serde(deny_unknown_fields)]
23pub struct Member {
24 #[serde(rename = "_id")]
25 pub id: MemberCompositeKey,
26 #[serde(default, skip_serializing_if = "Option::is_none")]
27 pub nickname: Option<String>,
28 #[serde(default, skip_serializing_if = "Option::is_none")]
29 pub avatar: Option<Attachment>,
30 #[serde(default, skip_serializing_if = "Vec::is_empty")]
31 pub roles: Vec<RoleId>,
32}
33
34#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
37#[serde(deny_unknown_fields)]
38pub struct Ban {
39 #[serde(rename = "_id")]
40 pub id: MemberCompositeKey,
41 #[serde(default, skip_serializing_if = "Option::is_none")]
42 pub reason: Option<String>,
43}
44
45pub type PermissionTuple = (ServerPermissions, ChannelPermissions);
48
49bitflags::bitflags! {
50 #[derive(Serialize, Deserialize)]
51 #[serde(transparent)]
52 #[doc = "Server permissions"]
53 pub struct ServerPermissions: u32 {
54 const VIEW = 0b00000000000000000000000000000001; const MANAGE_ROLES = 0b00000000000000000000000000000010; const MANAGE_CHANNELS = 0b00000000000000000000000000000100; const MANAGE_SERVER = 0b00000000000000000000000000001000; const KICK_MEMBERS = 0b00000000000000000000000000010000; const BAN_MEMBERS = 0b00000000000000000000000000100000; const CHANGE_NICKNAME = 0b00000000000000000001000000000000; const MANAGE_NICKNAMES = 0b00000000000000000010000000000000; const CHANGE_AVATAR = 0b00000000000000000100000000000000; const REMOVE_AVATARS = 0b00000000000000001000000000000000; }
65}
66
67pub type Color = String;
70
71#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
74#[serde(deny_unknown_fields)]
75pub struct Role {
76 pub name: String,
78 pub permissions: PermissionTuple,
80 #[serde(rename = "colour", default, skip_serializing_if = "Option::is_none")]
91 pub color: Option<Color>,
92 #[serde(default, skip_serializing_if = "Option::is_none")]
94 pub hoist: Option<bool>,
95 #[serde(default, skip_serializing_if = "Option::is_none")]
99 pub rank: Option<usize>,
100}
101
102#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
105#[serde(deny_unknown_fields)]
106pub struct RoleInformation {
107 pub name: String,
108 #[serde(rename = "colour", default, skip_serializing_if = "Option::is_none")]
109 pub color: Option<Color>,
110 #[serde(default, skip_serializing_if = "Option::is_none")]
111 pub hoist: Option<bool>,
112 #[serde(default, skip_serializing_if = "Option::is_none")]
113 pub rank: Option<usize>,
114}
115
116#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
119#[serde(deny_unknown_fields)]
120pub struct Category {
121 pub id: CategoryId,
122 pub title: String,
123 pub channels: Vec<ChannelId>,
124}
125
126#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
129#[serde(deny_unknown_fields)]
130pub struct SystemMessageChannels {
131 #[serde(default, skip_serializing_if = "Option::is_none")]
132 pub user_joined: Option<ChannelId>,
133 #[serde(default, skip_serializing_if = "Option::is_none")]
134 pub user_left: Option<ChannelId>,
135 #[serde(default, skip_serializing_if = "Option::is_none")]
136 pub user_kicked: Option<ChannelId>,
137 #[serde(default, skip_serializing_if = "Option::is_none")]
138 pub user_banned: Option<ChannelId>,
139}
140
141#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
145#[serde(deny_unknown_fields)]
146pub struct Server {
147 #[serde(rename = "_id")]
148 pub id: ServerId,
149 #[serde(default, skip_serializing_if = "Option::is_none")]
150 pub nonce: Option<String>,
151 pub owner: UserId,
152 pub name: String,
153 #[serde(default, skip_serializing_if = "Option::is_none")]
154 pub description: Option<String>,
155 pub channels: Vec<ChannelId>,
156 #[serde(default, skip_serializing_if = "Vec::is_empty")]
157 pub categories: Vec<Category>,
158 #[serde(default, skip_serializing_if = "Option::is_none")]
159 pub system_messages: Option<SystemMessageChannels>,
160 #[serde(default, skip_serializing_if = "Option::is_none")]
161 pub roles: Option<RolesObject>,
162 pub default_permissions: PermissionTuple,
163 #[serde(default, skip_serializing_if = "Option::is_none")]
164 pub icon: Option<Attachment>,
165 #[serde(default, skip_serializing_if = "Option::is_none")]
166 pub banner: Option<Attachment>,
167 #[serde(default, skip_serializing_if = "Option::is_none")]
168 pub nsfw: Option<bool>,
169 #[serde(default, skip_serializing_if = "Option::is_none")]
170 pub flags: Option<ServerFlags>,
171}
172
173bitflags::bitflags! {
176 #[derive(Serialize, Deserialize)]
177 #[serde(transparent)]
178 pub struct ServerFlags: u32 {
179 const OFFICIAL_REVOLT_SERVER = 1;
180 const VERIFIED_COMMUNITY_SERVER = 2;
181 }
182}
183
184#[derive(Serialize, Deserialize, Default, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
191#[serde(deny_unknown_fields)]
192pub struct PartialMember {
193 #[serde(rename = "_id", default, skip_serializing_if = "Option::is_none")]
194 pub id: Option<MemberId>,
195 #[serde(default, skip_serializing_if = "Option::is_none")]
196 pub nickname: Option<String>,
197 #[serde(default, skip_serializing_if = "Option::is_none")]
198 pub avatar: Option<Attachment>,
199 #[serde(default, skip_serializing_if = "Option::is_none")]
200 pub roles: Option<Vec<RoleId>>,
201}
202
203impl PartialMember {
204 pub fn patch(self, member: &mut Member) {
206 let PartialMember {
207 id: pid,
208 nickname: pnickname,
209 avatar: pavatar,
210 roles: proles,
211 } = self;
212 let Member {
213 id,
214 nickname,
215 avatar,
216 roles,
217 } = member;
218
219 if let Some(pid) = pid {
220 *id = pid;
221 }
222 if let Some(pnickname) = pnickname {
223 *nickname = Some(pnickname);
224 }
225 if let Some(pavatar) = pavatar {
226 *avatar = Some(pavatar);
227 }
228 if let Some(proles) = proles {
229 *roles = proles;
230 }
231 }
232}
233
234#[derive(Serialize, Deserialize, Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
236pub enum MemberField {
237 Nickname,
238 Avatar,
239}
240
241impl MemberField {
242 pub fn remove_patch(self, member: &mut Member) {
244 match self {
245 Self::Nickname => member.nickname = None,
246 Self::Avatar => member.avatar = None,
247 }
248 }
249}
250
251#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
254#[serde(transparent)]
255pub struct RolesObject(HashMap<RoleId, Role>);
256
257impl RolesObject {
258 pub fn iter(&self) -> RolesIter {
259 RolesIter(self.0.iter())
260 }
261
262 pub fn get(&self, id: &RoleId) -> Option<&Role> {
263 self.0.get(id)
264 }
265
266 pub fn patch_role(&mut self, role_id: &RoleId, patch: PartialRole, remove: Option<RoleField>) {
267 if let Some(refr) = self.0.get_mut(role_id) {
268 patch.patch(refr);
269
270 if let Some(remove) = remove {
271 remove.remove_patch(refr);
272 }
273 }
274 }
275
276 pub fn remove(&mut self, id: &RoleId) {
277 self.0.remove(id);
278 }
279}
280
281pub struct RolesIter<'a>(std::collections::hash_map::Iter<'a, RoleId, Role>);
282
283impl<'a> Iterator for RolesIter<'a> {
284 type Item = (&'a RoleId, &'a Role);
285
286 fn next(&mut self) -> Option<Self::Item> {
287 self.0.next()
288 }
289}
290
291#[derive(Serialize, Deserialize, Debug, Default, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
294#[serde(deny_unknown_fields)]
295pub struct PartialRole {
296 #[serde(default, skip_serializing_if = "Option::is_none")]
297 pub name: Option<String>,
298 #[serde(default, skip_serializing_if = "Option::is_none")]
299 pub permissions: Option<(ServerPermissions, ChannelPermissions)>,
300 #[serde(rename = "colour", default, skip_serializing_if = "Option::is_none")]
301 pub color: Option<String>,
302 #[serde(default, skip_serializing_if = "Option::is_none")]
303 pub hoist: Option<bool>,
304 #[serde(default, skip_serializing_if = "Option::is_none")]
305 pub rank: Option<usize>,
306}
307
308impl PartialRole {
309 pub fn patch(self, role: &mut Role) {
311 let PartialRole {
312 name: pname,
313 permissions: ppermissions,
314 color: pcolor,
315 hoist: phoist,
316 rank: prank,
317 } = self;
318 let Role {
319 name,
320 permissions,
321 color,
322 hoist,
323 rank,
324 } = role;
325
326 if let Some(pname) = pname {
327 *name = pname;
328 }
329 if let Some(ppermissions) = ppermissions {
330 *permissions = ppermissions;
331 }
332 if let Some(pcolor) = pcolor {
333 *color = Some(pcolor);
334 }
335 if let Some(phoist) = phoist {
336 *hoist = Some(phoist);
337 }
338 if let Some(prank) = prank {
339 *rank = Some(prank);
340 }
341 }
342}
343
344#[derive(Serialize, Deserialize, Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
346pub enum RoleField {
347 #[serde(rename = "Colour")]
348 Color,
349}
350
351impl RoleField {
352 pub fn remove_patch(self, role: &mut Role) {
354 match self {
355 Self::Color => role.color = None,
356 }
357 }
358}
359
360#[derive(Serialize, Deserialize, Default, Debug, Clone, Eq, PartialEq)]
363#[serde(deny_unknown_fields)]
364pub struct PartialServer {
365 #[serde(rename = "_id", default, skip_serializing_if = "Option::is_none")]
366 pub id: Option<ServerId>,
367 #[serde(default, skip_serializing_if = "Option::is_none")]
368 pub nonce: Option<String>,
369 #[serde(default, skip_serializing_if = "Option::is_none")]
370 pub owner: Option<UserId>,
371 #[serde(default, skip_serializing_if = "Option::is_none")]
372 pub name: Option<String>,
373 #[serde(default, skip_serializing_if = "Option::is_none")]
374 pub description: Option<String>,
375 #[serde(default, skip_serializing_if = "Option::is_none")]
376 pub channels: Option<Vec<ChannelId>>,
377 #[serde(default, skip_serializing_if = "Option::is_none")]
378 pub categories: Option<Vec<Category>>,
379 #[serde(default, skip_serializing_if = "Option::is_none")]
380 pub system_messages: Option<SystemMessageChannels>,
381 #[serde(default, skip_serializing_if = "Option::is_none")]
382 pub roles: Option<RolesObject>,
383 #[serde(default, skip_serializing_if = "Option::is_none")]
384 pub default_permissions: Option<(ServerPermissions, ChannelPermissions)>,
385 #[serde(default, skip_serializing_if = "Option::is_none")]
386 pub icon: Option<Attachment>,
387 #[serde(default, skip_serializing_if = "Option::is_none")]
388 pub banner: Option<Attachment>,
389 #[serde(default, skip_serializing_if = "Option::is_none")]
390 pub nsfw: Option<bool>,
391 #[serde(default, skip_serializing_if = "Option::is_none")]
392 pub flags: Option<ServerFlags>,
393}
394
395impl PartialServer {
396 pub fn patch(self, serv: &mut Server) {
398 let PartialServer {
399 id: pid,
400 nonce: pnonce,
401 owner: powner,
402 name: pname,
403 description: pdescription,
404 channels: pchannels,
405 categories: pcategories,
406 system_messages: psystem_messages,
407 roles: proles,
408 default_permissions: pdefault_permissions,
409 icon: picon,
410 banner: pbanner,
411 nsfw: pnsfw,
412 flags: pflags,
413 } = self;
414 let Server {
415 id,
416 nonce,
417 owner,
418 name,
419 description,
420 channels,
421 categories,
422 system_messages,
423 roles,
424 default_permissions,
425 icon,
426 banner,
427 nsfw,
428 flags,
429 } = serv;
430
431 if let Some(pid) = pid {
432 *id = pid;
433 }
434 if let Some(pnonce) = pnonce {
435 *nonce = Some(pnonce);
436 }
437 if let Some(powner) = powner {
438 *owner = powner;
439 }
440 if let Some(pname) = pname {
441 *name = pname;
442 }
443 if let Some(pdescription) = pdescription {
444 *description = Some(pdescription);
445 }
446 if let Some(pchannels) = pchannels {
447 *channels = pchannels;
448 }
449 if let Some(pcategories) = pcategories {
450 *categories = pcategories;
451 }
452 if let Some(psystem_messages) = psystem_messages {
453 *system_messages = Some(psystem_messages);
454 }
455 if let Some(proles) = proles {
456 *roles = Some(proles);
457 }
458 if let Some(pdefault_permissions) = pdefault_permissions {
459 *default_permissions = pdefault_permissions;
460 }
461 if let Some(picon) = picon {
462 *icon = Some(picon);
463 }
464 if let Some(pbanner) = pbanner {
465 *banner = Some(pbanner);
466 }
467 if let Some(pnsfw) = pnsfw {
468 *nsfw = Some(pnsfw);
469 }
470 if let Some(pflags) = pflags {
471 *flags = Some(pflags);
472 }
473 }
474}
475
476#[derive(Serialize, Deserialize, Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
478pub enum ServerField {
479 Icon,
480 Banner,
481 Description,
482}
483
484impl ServerField {
485 pub fn remove_patch(self, server: &mut Server) {
487 match self {
488 Self::Icon => server.icon = None,
489 Self::Banner => server.banner = None,
490 Self::Description => server.description = None,
491 }
492 }
493}