1use std::{collections::HashMap, fmt::Display};
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use crate::{
7 autumn::{Attachment, AttachmentId},
8 id::{ChannelId, MessageId, RoleId, ServerId, UserId},
9 january::Embed,
10};
11
12#[derive(Deserialize, Serialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
24#[serde(deny_unknown_fields)]
25pub struct SavedMessagesChannel {
26 #[serde(rename = "_id")]
27 pub id: ChannelId,
28 pub user: UserId,
29
30 #[serde(default, skip_serializing_if = "Option::is_none")]
31 pub nonce: Option<String>,
32}
33
34#[derive(Deserialize, Serialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
37#[serde(deny_unknown_fields)]
38pub struct DirectMessageChannel {
39 #[serde(rename = "_id")]
40 pub id: ChannelId,
41 pub active: bool,
42 pub recipients: Vec<UserId>,
43 #[serde(default, skip_serializing_if = "Option::is_none")]
44 pub last_message_id: Option<MessageId>,
45
46 #[serde(default, skip_serializing_if = "Option::is_none")]
48 pub nonce: Option<String>,
49}
50
51#[derive(Deserialize, Serialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
54#[serde(deny_unknown_fields)]
55pub struct GroupChannel {
56 #[serde(rename = "_id")]
57 pub id: ChannelId,
58 pub recipients: Vec<UserId>,
60
61 pub name: String,
63
64 pub owner: UserId,
66
67 #[serde(default, skip_serializing_if = "Option::is_none")]
68 pub description: Option<String>,
69
70 #[serde(default, skip_serializing_if = "Option::is_none")]
71 pub last_message_id: Option<MessageId>,
72
73 #[serde(default, skip_serializing_if = "Option::is_none")]
74 pub icon: Option<Attachment>,
75
76 #[serde(default, skip_serializing_if = "Option::is_none")]
77 pub permissions: Option<ChannelPermissions>,
78
79 #[serde(default, skip_serializing_if = "Option::is_none")]
80 pub nsfw: Option<bool>,
81
82 #[serde(default, skip_serializing_if = "Option::is_none")]
84 pub nonce: Option<String>,
85}
86
87#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq)]
90#[serde(deny_unknown_fields)]
91pub struct ServerChannel {
92 #[serde(rename = "_id")]
93 pub id: ChannelId,
94
95 pub server: ServerId,
96
97 pub name: String,
98
99 #[serde(default, skip_serializing_if = "Option::is_none")]
100 pub description: Option<String>,
101
102 #[serde(default, skip_serializing_if = "Option::is_none")]
103 pub icon: Option<Attachment>,
104
105 #[serde(default, skip_serializing_if = "Option::is_none")]
107 pub default_permissions: Option<ChannelPermissions>,
108
109 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
111 pub role_permissions: HashMap<RoleId, ChannelPermissions>,
112
113 #[serde(default, skip_serializing_if = "Option::is_none")]
114 pub nsfw: Option<bool>,
115}
116
117#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq)]
120#[serde(deny_unknown_fields)]
121pub struct TextChannel {
122 #[serde(flatten)]
123 pub server_channel: ServerChannel,
124
125 pub last_message_id: Option<MessageId>,
126
127 #[serde(default, skip_serializing_if = "Option::is_none")]
129 pub nonce: Option<String>,
130}
131
132#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq)]
135#[serde(deny_unknown_fields)]
136pub struct VoiceChannel {
137 #[serde(flatten)]
138 pub server_channel: ServerChannel,
139
140 #[serde(default, skip_serializing_if = "Option::is_none")]
142 pub nonce: Option<String>,
143}
144
145#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq)]
149#[serde(tag = "channel_type")]
150#[serde(deny_unknown_fields)]
151pub enum Channel {
152 SavedMessages(SavedMessagesChannel),
153 DirectMessage(DirectMessageChannel),
154 Group(GroupChannel),
155 TextChannel(TextChannel),
156 VoiceChannel(VoiceChannel),
157}
158
159#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
162#[serde(deny_unknown_fields)]
163pub struct Message {
164 #[serde(rename = "_id")]
165 pub id: MessageId,
166 #[serde(default, skip_serializing_if = "Option::is_none")]
167 pub nonce: Option<String>,
168 pub channel: ChannelId,
169 pub author: UserId,
170 pub content: MessageContent,
171 #[serde(default, skip_serializing_if = "Vec::is_empty")]
172 pub attachments: Vec<Attachment>,
173 #[serde(default, skip_serializing_if = "Option::is_none")]
174 pub edited: Option<Date>,
175 #[serde(default, skip_serializing_if = "Vec::is_empty")]
176 pub embeds: Vec<Embed>,
177 #[serde(default, skip_serializing_if = "Vec::is_empty")]
178 pub mentions: Vec<UserId>,
179 #[serde(default, skip_serializing_if = "Vec::is_empty")]
180 pub replies: Vec<MessageId>,
181}
182
183#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
184#[serde(untagged)]
185#[serde(deny_unknown_fields)]
186pub enum MessageContent {
187 Content(String),
188 SystemMessage(SystemMessage),
189}
190
191#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
192#[serde(tag = "type", rename_all = "snake_case")]
193#[serde(deny_unknown_fields)]
194pub enum SystemMessage {
195 Text { content: String },
196 UserAdded { id: UserId, by: UserId },
197 UserRemove { id: UserId, by: UserId },
198 UserJoined { id: UserId },
199 UserLeft { id: UserId },
200 UserKicked { id: UserId },
201 UserBanned { id: UserId },
202 ChannelRenamed { name: String, by: UserId },
203 ChannelDescriptionChanged { by: UserId },
204 ChannelIconChanged { by: UserId },
205}
206
207#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
213#[serde(deny_unknown_fields)]
214pub struct ReplyData {
215 pub id: MessageId,
216 pub mention: bool,
217}
218
219bitflags::bitflags! {
220 #[derive(Serialize, Deserialize)]
221 #[serde(transparent)]
222 #[doc = "Channel permissions"]
223 pub struct ChannelPermissions: u32 {
224 const VIEW = 0b00000000000000000000000000000001; const SEND_MESSAGE = 0b00000000000000000000000000000010; const MANAGE_MESSAGES = 0b00000000000000000000000000000100; const MANAGE_CHANNEL = 0b00000000000000000000000000001000; const VOICE_CALL = 0b00000000000000000000000000010000; const INVITE_OTHERS = 0b00000000000000000000000000100000; const EMBED_LINKS = 0b00000000000000000000000001000000; const UPLOAD_FILES = 0b00000000000000000000000010000000; }
233}
234
235impl Channel {
236 pub fn id(&self) -> ChannelId {
237 match self {
238 Self::SavedMessages(SavedMessagesChannel { id, .. }) => *id,
239 Self::DirectMessage(DirectMessageChannel { id, .. }) => *id,
240 Self::Group(GroupChannel { id, .. }) => *id,
241 Self::TextChannel(TextChannel {
242 server_channel: ServerChannel { id, .. },
243 ..
244 }) => *id,
245 Self::VoiceChannel(VoiceChannel {
246 server_channel: ServerChannel { id, .. },
247 ..
248 }) => *id,
249 }
250 }
251
252 pub fn server_id(&self) -> Option<ServerId> {
253 match self {
254 Channel::TextChannel(TextChannel {
255 server_channel: ServerChannel { server, .. },
256 ..
257 })
258 | Channel::VoiceChannel(VoiceChannel {
259 server_channel: ServerChannel { server, .. },
260 ..
261 }) => Some(*server),
262 _ => None,
263 }
264 }
265}
266
267#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
268pub enum ChannelType {
269 SavedMessages,
270 DirectMessage,
271 Group,
272 TextChannel,
273 VoiceChannel,
274}
275
276#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq)]
279#[serde(deny_unknown_fields)]
280pub struct PartialChannel {
281 #[serde(default, skip_serializing_if = "Option::is_none")]
282 user: Option<UserId>,
283 #[serde(default, skip_serializing_if = "Option::is_none")]
284 nonce: Option<String>,
285
286 #[serde(default, skip_serializing_if = "Option::is_none")]
287 recipients: Option<Vec<UserId>>,
288 #[serde(default, skip_serializing_if = "Option::is_none")]
289 last_message_id: Option<MessageId>,
290
291 name: Option<String>,
292 #[serde(default, skip_serializing_if = "Option::is_none")]
293 owner: Option<UserId>,
294 #[serde(default, skip_serializing_if = "Option::is_none")]
295 description: Option<String>,
296 #[serde(default, skip_serializing_if = "Option::is_none")]
297 icon: Option<Attachment>,
298 #[serde(default, skip_serializing_if = "Option::is_none")]
299 permissions: Option<ChannelPermissions>,
300
301 #[serde(default, skip_serializing_if = "Option::is_none")]
302 server: Option<ServerId>,
303 #[serde(default, skip_serializing_if = "Option::is_none")]
304 default_permissions: Option<ChannelPermissions>,
305 #[serde(default, skip_serializing_if = "Option::is_none")]
306 role_permissions: Option<HashMap<RoleId, ChannelPermissions>>,
307
308 #[serde(default, skip_serializing_if = "Option::is_none")]
309 active: Option<bool>,
310
311 #[serde(default, skip_serializing_if = "Option::is_none")]
312 nsfw: Option<bool>,
313
314 #[serde(default, skip_serializing_if = "Option::is_none")]
315 channel_type: Option<ChannelType>,
316}
317
318impl PartialChannel {
319 pub fn patch(self, ch: &mut Channel) {
321 match ch {
322 Channel::SavedMessages(SavedMessagesChannel { id: _, user, nonce }) => {
323 if let Some(puser) = self.user {
324 *user = puser;
325 }
326 if let Some(pnonce) = self.nonce {
327 *nonce = Some(pnonce);
328 }
329 }
330 Channel::DirectMessage(DirectMessageChannel {
331 id: _,
332 recipients,
333 last_message_id,
334 nonce,
335 active,
336 }) => {
337 if let Some(precipients) = self.recipients {
338 *recipients = precipients;
339 }
340 if let Some(plast_message_id) = self.last_message_id {
341 *last_message_id = Some(plast_message_id);
342 }
343 if let Some(pnonce) = self.nonce {
344 *nonce = Some(pnonce);
345 }
346
347 if let Some(pactive) = self.active {
348 *active = pactive;
349 }
350 }
351 Channel::Group(GroupChannel {
352 id: _,
353 recipients,
354 name,
355 owner,
356 description,
357 last_message_id,
358 icon,
359 permissions,
360 nsfw,
361 nonce,
362 }) => {
363 if let Some(precipients) = self.recipients {
364 *recipients = precipients;
365 }
366 if let Some(pname) = self.name {
367 *name = pname;
368 }
369 if let Some(powner) = self.owner {
370 *owner = powner;
371 }
372 if let Some(pdescription) = self.description {
373 *description = Some(pdescription);
374 }
375 if let Some(plast_message_id) = self.last_message_id {
376 *last_message_id = Some(plast_message_id);
377 }
378 if let Some(picon) = self.icon {
379 *icon = Some(picon);
380 }
381 if let Some(ppermissions) = self.permissions {
382 *permissions = Some(ppermissions);
383 }
384 if let Some(pnsfw) = self.nsfw {
385 *nsfw = Some(pnsfw);
386 }
387 if let Some(pnonce) = self.nonce {
388 *nonce = Some(pnonce);
389 }
390 }
391 Channel::TextChannel(TextChannel {
392 server_channel:
393 ServerChannel {
394 id: _,
395 server,
396 name,
397 description,
398 icon,
399 default_permissions,
400 role_permissions,
401 nsfw,
402 },
403 last_message_id: _,
404 nonce,
405 }) => {
406 if let Some(pserver) = self.server {
407 *server = pserver;
408 }
409 if let Some(pname) = self.name {
410 *name = pname;
411 }
412 if let Some(pdescription) = self.description {
413 *description = Some(pdescription);
414 }
415 if let Some(picon) = self.icon {
416 *icon = Some(picon);
417 }
418 if let Some(pdefault_permissions) = self.default_permissions {
419 *default_permissions = Some(pdefault_permissions);
420 }
421 if let Some(prole_permissions) = self.role_permissions {
422 *role_permissions = prole_permissions;
423 }
424 if let Some(pnsfw) = self.nsfw {
425 *nsfw = Some(pnsfw);
426 }
427 if let Some(pnonce) = self.nonce {
431 *nonce = Some(pnonce);
432 }
433 }
434 Channel::VoiceChannel(VoiceChannel {
435 server_channel:
436 ServerChannel {
437 id: _,
438 server,
439 name,
440 description,
441 icon,
442 default_permissions,
443 role_permissions,
444 nsfw,
445 },
446 nonce,
447 }) => {
448 if let Some(pserver) = self.server {
449 *server = pserver;
450 }
451 if let Some(pname) = self.name {
452 *name = pname;
453 }
454 if let Some(pdescription) = self.description {
455 *description = Some(pdescription);
456 }
457 if let Some(picon) = self.icon {
458 *icon = Some(picon);
459 }
460 if let Some(pdefault_permissions) = self.default_permissions {
461 *default_permissions = Some(pdefault_permissions);
462 }
463 if let Some(prole_permissions) = self.role_permissions {
464 *role_permissions = prole_permissions;
465 }
466 if let Some(pnsfw) = self.nsfw {
467 *nsfw = Some(pnsfw);
468 }
469 if let Some(pnonce) = self.nonce {
470 *nonce = Some(pnonce);
471 }
472 }
473 }
474 }
475}
476
477#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
480#[serde(deny_unknown_fields)]
481pub struct PartialMessage {
482 #[serde(rename = "_id", default, skip_serializing_if = "Option::is_none")]
483 pub id: Option<MessageId>,
484 #[serde(default, skip_serializing_if = "Option::is_none")]
485 pub nonce: Option<String>,
486 #[serde(default, skip_serializing_if = "Option::is_none")]
487 pub channel: Option<ChannelId>,
488 #[serde(default, skip_serializing_if = "Option::is_none")]
489 pub author: Option<UserId>,
490 #[serde(default, skip_serializing_if = "Option::is_none")]
491 pub content: Option<MessageContent>,
492 #[serde(default, skip_serializing_if = "Option::is_none")]
493 pub attachments: Option<Vec<Attachment>>,
494 #[serde(default, skip_serializing_if = "Option::is_none")]
495 pub edited: Option<Date>,
496 #[serde(default, skip_serializing_if = "Option::is_none")]
497 pub embeds: Option<Vec<Embed>>,
498 #[serde(default, skip_serializing_if = "Option::is_none")]
499 pub mentions: Option<Vec<UserId>>,
500 #[serde(default, skip_serializing_if = "Option::is_none")]
501 pub replies: Option<Vec<MessageId>>,
502}
503
504impl PartialMessage {
505 pub fn patch(self, m: &mut Message) {
507 let PartialMessage {
508 id: pid,
509 nonce: pnonce,
510 channel: pchannel,
511 author: pauthor,
512 content: pcontent,
513 attachments: pattachments,
514 edited: pedited,
515 embeds: pembeds,
516 mentions: pmentions,
517 replies: preplies,
518 } = self;
519 let Message {
520 id,
521 nonce,
522 channel,
523 author,
524 content,
525 attachments,
526 edited,
527 embeds,
528 mentions,
529 replies,
530 } = m;
531
532 if let Some(pid) = pid {
533 *id = pid;
534 }
535 if let Some(pnonce) = pnonce {
536 *nonce = Some(pnonce);
537 }
538 if let Some(pchannel) = pchannel {
539 *channel = pchannel;
540 }
541 if let Some(pauthor) = pauthor {
542 *author = pauthor;
543 }
544 if let Some(pcontent) = pcontent {
545 *content = pcontent;
546 }
547 if let Some(pattachments) = pattachments {
548 *attachments = pattachments;
549 }
550 if let Some(pedited) = pedited {
551 *edited = Some(pedited);
552 }
553 if let Some(pembeds) = pembeds {
554 *embeds = pembeds;
555 }
556 if let Some(pmentions) = pmentions {
557 *mentions = pmentions;
558 }
559 if let Some(preplies) = preplies {
560 *replies = preplies;
561 }
562 }
563}
564
565#[derive(Serialize, Deserialize, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
567#[serde(from = "WrappedDate", into = "WrappedDate")]
568pub struct Date(pub DateTime<Utc>);
569
570impl From<Date> for WrappedDate {
571 fn from(d: Date) -> Self {
572 Self { date: d.0 }
573 }
574}
575
576impl From<WrappedDate> for Date {
577 fn from(d: WrappedDate) -> Self {
578 Self(d.date)
579 }
580}
581
582#[derive(Serialize, Deserialize)]
583#[serde(deny_unknown_fields)]
584struct WrappedDate {
585 #[serde(rename = "$date")]
586 date: DateTime<Utc>,
587}
588
589#[derive(Serialize, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
591pub struct ChannelEditPatch {
592 #[serde(skip_serializing_if = "Option::is_none")]
593 pub name: Option<String>,
594 #[serde(skip_serializing_if = "Option::is_none")]
595 pub description: Option<String>,
596 #[serde(skip_serializing_if = "Option::is_none")]
597 pub icon: Option<AttachmentId>,
598 #[serde(skip_serializing_if = "Option::is_none")]
599 pub remove: Option<ChannelField>,
600}
601
602#[derive(Serialize, Deserialize, Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
604pub enum ChannelField {
605 Description,
606 Icon,
607}
608
609impl ChannelField {
610 pub fn remove_patch(self, channel: &mut Channel) {
612 match self {
613 Self::Description => match channel {
614 Channel::Group(GroupChannel { description, .. })
615 | Channel::TextChannel(TextChannel {
616 server_channel: ServerChannel { description, .. },
617 ..
618 })
619 | Channel::VoiceChannel(VoiceChannel {
620 server_channel: ServerChannel { description, .. },
621 ..
622 }) => *description = None,
623 Channel::SavedMessages { .. } | Channel::DirectMessage { .. } => {}
624 },
625 Self::Icon => match channel {
626 Channel::Group(GroupChannel { icon, .. })
627 | Channel::TextChannel(TextChannel {
628 server_channel: ServerChannel { icon, .. },
629 ..
630 })
631 | Channel::VoiceChannel(VoiceChannel {
632 server_channel: ServerChannel { icon, .. },
633 ..
634 }) => *icon = None,
635 Channel::SavedMessages { .. } | Channel::DirectMessage { .. } => {}
636 },
637 }
638 }
639}
640
641#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
643#[serde(transparent)]
644pub struct ChannelInviteCode(String);
645
646impl Display for ChannelInviteCode {
647 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
648 self.0.fmt(f)
649 }
650}
651
652#[derive(Deserialize, Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
653#[serde(deny_unknown_fields)]
654pub struct CreateChannelInviteResponse {
655 code: ChannelInviteCode,
656}
657
658#[derive(Debug, Default, Serialize)]
660pub struct MessageFilter {
661 #[serde(skip_serializing_if = "Option::is_none")]
662 pub limit: Option<usize>,
663 #[serde(skip_serializing_if = "Option::is_none")]
664 pub before: Option<MessageId>,
665 #[serde(skip_serializing_if = "Option::is_none")]
666 pub after: Option<MessageId>,
667 pub sort: MessageFilterSortDirection,
668 #[serde(skip_serializing_if = "Option::is_none")]
669 pub nearby: Option<MessageId>,
670 #[serde(skip_serializing_if = "Option::is_none")]
671 pub include_users: Option<bool>,
672}
673
674#[derive(Debug, Serialize)]
676pub enum MessageFilterSortDirection {
677 Latest,
679 Oldest,
681}
682
683impl Default for MessageFilterSortDirection {
684 fn default() -> Self {
685 Self::Latest
686 }
687}
688
689#[derive(Serialize, Deserialize, Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
691pub enum ServerChannelType {
692 Text,
693 Voice,
694}