1use iso8601_timestamp::Timestamp;
2use revolt_models::v0::*;
3use revolt_permissions::{calculate_user_permissions, UserPermission};
4
5use crate::{util::permissions::DatabasePermissionQuery, Database};
6
7impl crate::Bot {
8 pub fn into_public_bot(self, user: crate::User) -> PublicBot {
9 #[cfg(debug_assertions)]
10 assert_eq!(self.id, user.id);
11
12 PublicBot {
13 id: self.id,
14 username: user.username,
15 avatar: user.avatar.map(|x| x.id).unwrap_or_default(),
16 description: user
17 .profile
18 .and_then(|profile| profile.content)
19 .unwrap_or_default(),
20 }
21 }
22}
23
24impl From<crate::Bot> for Bot {
25 fn from(value: crate::Bot) -> Self {
26 Bot {
27 id: value.id,
28 owner_id: value.owner,
29 token: value.token,
30 public: value.public,
31 analytics: value.analytics,
32 discoverable: value.discoverable,
33 interactions_url: value.interactions_url,
34 terms_of_service_url: value.terms_of_service_url,
35 privacy_policy_url: value.privacy_policy_url,
36 flags: value.flags.unwrap_or_default() as u32,
37 }
38 }
39}
40
41impl From<FieldsBot> for crate::FieldsBot {
42 fn from(value: FieldsBot) -> Self {
43 match value {
44 FieldsBot::InteractionsURL => crate::FieldsBot::InteractionsURL,
45 FieldsBot::Token => crate::FieldsBot::Token,
46 }
47 }
48}
49
50impl From<crate::FieldsBot> for FieldsBot {
51 fn from(value: crate::FieldsBot) -> Self {
52 match value {
53 crate::FieldsBot::InteractionsURL => FieldsBot::InteractionsURL,
54 crate::FieldsBot::Token => FieldsBot::Token,
55 }
56 }
57}
58
59impl From<crate::Invite> for Invite {
60 fn from(value: crate::Invite) -> Self {
61 match value {
62 crate::Invite::Group {
63 code,
64 creator,
65 channel,
66 } => Invite::Group {
67 code,
68 creator,
69 channel,
70 },
71 crate::Invite::Server {
72 code,
73 server,
74 creator,
75 channel,
76 } => Invite::Server {
77 code,
78 server,
79 creator,
80 channel,
81 },
82 }
83 }
84}
85
86impl From<crate::ChannelUnread> for ChannelUnread {
87 fn from(value: crate::ChannelUnread) -> Self {
88 ChannelUnread {
89 id: value.id.into(),
90 last_id: value.last_id,
91 mentions: value.mentions.unwrap_or_default(),
92 }
93 }
94}
95
96impl From<crate::ChannelCompositeKey> for ChannelCompositeKey {
97 fn from(value: crate::ChannelCompositeKey) -> Self {
98 ChannelCompositeKey {
99 channel: value.channel,
100 user: value.user,
101 }
102 }
103}
104
105impl From<crate::Webhook> for Webhook {
106 fn from(value: crate::Webhook) -> Self {
107 Webhook {
108 id: value.id,
109 name: value.name,
110 avatar: value.avatar.map(|file| file.into()),
111 creator_id: value.creator_id,
112 channel_id: value.channel_id,
113 token: value.token,
114 permissions: value.permissions,
115 }
116 }
117}
118
119impl From<crate::PartialWebhook> for PartialWebhook {
120 fn from(value: crate::PartialWebhook) -> Self {
121 PartialWebhook {
122 id: value.id,
123 name: value.name,
124 avatar: value.avatar.map(|file| file.into()),
125 creator_id: value.creator_id,
126 channel_id: value.channel_id,
127 token: value.token,
128 permissions: value.permissions,
129 }
130 }
131}
132
133impl From<FieldsWebhook> for crate::FieldsWebhook {
134 fn from(_value: FieldsWebhook) -> Self {
135 Self::Avatar
136 }
137}
138
139impl From<crate::FieldsWebhook> for FieldsWebhook {
140 fn from(_value: crate::FieldsWebhook) -> Self {
141 Self::Avatar
142 }
143}
144
145impl From<crate::Channel> for Channel {
146 #[allow(deprecated)]
147 fn from(value: crate::Channel) -> Self {
148 match value {
149 crate::Channel::SavedMessages { id, user } => Channel::SavedMessages { id, user },
150 crate::Channel::DirectMessage {
151 id,
152 active,
153 recipients,
154 last_message_id,
155 } => Channel::DirectMessage {
156 id,
157 active,
158 recipients,
159 last_message_id,
160 },
161 crate::Channel::Group {
162 id,
163 name,
164 owner,
165 description,
166 recipients,
167 icon,
168 last_message_id,
169 permissions,
170 nsfw,
171 } => Channel::Group {
172 id,
173 name,
174 owner,
175 description,
176 recipients,
177 icon: icon.map(|file| file.into()),
178 last_message_id,
179 permissions,
180 nsfw,
181 },
182 crate::Channel::TextChannel {
183 id,
184 server,
185 name,
186 description,
187 icon,
188 last_message_id,
189 default_permissions,
190 role_permissions,
191 nsfw,
192 voice,
193 slowmode,
194 } => Channel::TextChannel {
195 id,
196 server,
197 name,
198 description,
199 icon: icon.map(|file| file.into()),
200 last_message_id,
201 default_permissions,
202 role_permissions,
203 nsfw,
204 voice: voice.map(|voice| voice.into()),
205 slowmode,
206 },
207 }
208 }
209}
210
211impl From<Channel> for crate::Channel {
212 #[allow(deprecated)]
213 fn from(value: Channel) -> crate::Channel {
214 match value {
215 Channel::SavedMessages { id, user } => crate::Channel::SavedMessages { id, user },
216 Channel::DirectMessage {
217 id,
218 active,
219 recipients,
220 last_message_id,
221 } => crate::Channel::DirectMessage {
222 id,
223 active,
224 recipients,
225 last_message_id,
226 },
227 Channel::Group {
228 id,
229 name,
230 owner,
231 description,
232 recipients,
233 icon,
234 last_message_id,
235 permissions,
236 nsfw,
237 } => crate::Channel::Group {
238 id,
239 name,
240 owner,
241 description,
242 recipients,
243 icon: icon.map(|file| file.into()),
244 last_message_id,
245 permissions,
246 nsfw,
247 },
248 Channel::TextChannel {
249 id,
250 server,
251 name,
252 description,
253 icon,
254 last_message_id,
255 default_permissions,
256 role_permissions,
257 nsfw,
258 voice,
259 slowmode,
260 } => crate::Channel::TextChannel {
261 id,
262 server,
263 name,
264 description,
265 icon: icon.map(|file| file.into()),
266 last_message_id,
267 default_permissions,
268 role_permissions,
269 nsfw,
270 voice: voice.map(|voice| voice.into()),
271 slowmode,
272 },
273 }
274 }
275}
276
277impl From<crate::PartialChannel> for PartialChannel {
278 fn from(value: crate::PartialChannel) -> Self {
279 PartialChannel {
280 name: value.name,
281 owner: value.owner,
282 description: value.description,
283 icon: value.icon.map(|file| file.into()),
284 nsfw: value.nsfw,
285 active: value.active,
286 permissions: value.permissions,
287 role_permissions: value.role_permissions,
288 default_permissions: value.default_permissions,
289 last_message_id: value.last_message_id,
290 voice: value.voice.map(|voice| voice.into()),
291 slowmode: value.slowmode,
292 }
293 }
294}
295
296impl From<PartialChannel> for crate::PartialChannel {
297 fn from(value: PartialChannel) -> crate::PartialChannel {
298 crate::PartialChannel {
299 name: value.name,
300 owner: value.owner,
301 description: value.description,
302 icon: value.icon.map(|file| file.into()),
303 nsfw: value.nsfw,
304 active: value.active,
305 permissions: value.permissions,
306 role_permissions: value.role_permissions,
307 default_permissions: value.default_permissions,
308 last_message_id: value.last_message_id,
309 voice: value.voice.map(|voice| voice.into()),
310 slowmode: value.slowmode,
311 }
312 }
313}
314
315impl From<FieldsChannel> for crate::FieldsChannel {
316 fn from(value: FieldsChannel) -> Self {
317 match value {
318 FieldsChannel::Description => crate::FieldsChannel::Description,
319 FieldsChannel::Icon => crate::FieldsChannel::Icon,
320 FieldsChannel::DefaultPermissions => crate::FieldsChannel::DefaultPermissions,
321 FieldsChannel::Voice => crate::FieldsChannel::Voice,
322 }
323 }
324}
325
326impl From<crate::FieldsChannel> for FieldsChannel {
327 fn from(value: crate::FieldsChannel) -> Self {
328 match value {
329 crate::FieldsChannel::Description => FieldsChannel::Description,
330 crate::FieldsChannel::Icon => FieldsChannel::Icon,
331 crate::FieldsChannel::DefaultPermissions => FieldsChannel::DefaultPermissions,
332 crate::FieldsChannel::Voice => FieldsChannel::Voice,
333 }
334 }
335}
336
337impl From<crate::Emoji> for Emoji {
338 fn from(value: crate::Emoji) -> Self {
339 Emoji {
340 id: value.id,
341 parent: value.parent.into(),
342 creator_id: value.creator_id,
343 name: value.name,
344 animated: value.animated,
345 nsfw: value.nsfw,
346 }
347 }
348}
349
350impl From<crate::EmojiParent> for EmojiParent {
351 fn from(value: crate::EmojiParent) -> Self {
352 match value {
353 crate::EmojiParent::Detached => EmojiParent::Detached,
354 crate::EmojiParent::Server { id } => EmojiParent::Server { id },
355 }
356 }
357}
358
359impl From<EmojiParent> for crate::EmojiParent {
360 fn from(value: EmojiParent) -> Self {
361 match value {
362 EmojiParent::Detached => crate::EmojiParent::Detached,
363 EmojiParent::Server { id } => crate::EmojiParent::Server { id },
364 }
365 }
366}
367
368impl From<crate::File> for File {
369 fn from(value: crate::File) -> Self {
370 File {
371 id: value.id,
372 tag: value.tag,
373 filename: value.filename,
374 metadata: value.metadata.into(),
375 content_type: value.content_type,
376 size: value.size,
377 deleted: value.deleted,
378 reported: value.reported,
379 message_id: value.message_id,
380 user_id: value.user_id,
381 server_id: value.server_id,
382 object_id: value.object_id,
383 }
384 }
385}
386
387impl From<File> for crate::File {
388 fn from(value: File) -> crate::File {
389 crate::File {
390 id: value.id,
391 tag: value.tag,
392 filename: value.filename,
393 metadata: value.metadata.into(),
394 content_type: value.content_type,
395 size: value.size,
396 deleted: value.deleted,
397 reported: value.reported,
398 message_id: value.message_id,
399 user_id: value.user_id,
400 server_id: value.server_id,
401 object_id: value.object_id,
402 hash: None,
403 uploaded_at: None,
404 uploader_id: None,
405 used_for: None,
406 }
407 }
408}
409
410impl From<crate::Metadata> for Metadata {
411 fn from(value: crate::Metadata) -> Self {
412 match value {
413 crate::Metadata::File => Metadata::File,
414 crate::Metadata::Text => Metadata::Text,
415 crate::Metadata::Image {
416 width,
417 height,
418 thumbhash,
419 animated,
420 } => Metadata::Image {
421 width: width as usize,
422 height: height as usize,
423 thumbhash,
424 animated,
425 },
426 crate::Metadata::Video { width, height } => Metadata::Video {
427 width: width as usize,
428 height: height as usize,
429 },
430 crate::Metadata::Audio => Metadata::Audio,
431 }
432 }
433}
434
435impl From<Metadata> for crate::Metadata {
436 fn from(value: Metadata) -> crate::Metadata {
437 match value {
438 Metadata::File => crate::Metadata::File,
439 Metadata::Text => crate::Metadata::Text,
440 Metadata::Image {
441 width,
442 height,
443 thumbhash,
444 animated,
445 } => crate::Metadata::Image {
446 width: width as isize,
447 height: height as isize,
448 thumbhash,
449 animated,
450 },
451 Metadata::Video { width, height } => crate::Metadata::Video {
452 width: width as isize,
453 height: height as isize,
454 },
455 Metadata::Audio => crate::Metadata::Audio,
456 }
457 }
458}
459
460impl crate::Message {
461 pub fn into_model(self, user: Option<User>, member: Option<Member>) -> Message {
462 Message {
463 id: self.id,
464 nonce: self.nonce,
465 channel: self.channel,
466 author: self.author,
467 user,
468 member,
469 webhook: self.webhook,
470 content: self.content,
471 system: self.system.map(Into::into),
472 attachments: self
473 .attachments
474 .map(|v| v.into_iter().map(|f| f.into()).collect()),
475 edited: self.edited,
476 embeds: self.embeds,
477 mentions: self.mentions,
478 role_mentions: self.role_mentions,
479 replies: self.replies,
480 reactions: self.reactions,
481 interactions: self.interactions.into(),
482 masquerade: self.masquerade.map(Into::into),
483 flags: self.flags.unwrap_or_default(),
484 pinned: self.pinned,
485 }
486 }
487}
488
489impl From<crate::PartialMessage> for PartialMessage {
490 fn from(value: crate::PartialMessage) -> Self {
491 PartialMessage {
492 id: value.id,
493 nonce: value.nonce,
494 channel: value.channel,
495 author: value.author,
496 user: None,
497 member: None,
498 webhook: value.webhook,
499 content: value.content,
500 system: value.system.map(Into::into),
501 attachments: value
502 .attachments
503 .map(|v| v.into_iter().map(|f| f.into()).collect()),
504 edited: value.edited,
505 embeds: value.embeds,
506 mentions: value.mentions,
507 role_mentions: value.role_mentions,
508 replies: value.replies,
509 reactions: value.reactions,
510 interactions: value.interactions.map(Into::into),
511 masquerade: value.masquerade.map(Into::into),
512 flags: value.flags,
513 pinned: value.pinned,
514 }
515 }
516}
517
518impl From<crate::SystemMessage> for SystemMessage {
519 fn from(value: crate::SystemMessage) -> Self {
520 match value {
521 crate::SystemMessage::ChannelDescriptionChanged { by } => {
522 Self::ChannelDescriptionChanged { by }
523 }
524 crate::SystemMessage::ChannelIconChanged { by } => Self::ChannelIconChanged { by },
525 crate::SystemMessage::ChannelOwnershipChanged { from, to } => {
526 Self::ChannelOwnershipChanged { from, to }
527 }
528 crate::SystemMessage::ChannelRenamed { name, by } => Self::ChannelRenamed { name, by },
529 crate::SystemMessage::Text { content } => Self::Text { content },
530 crate::SystemMessage::UserAdded { id, by } => Self::UserAdded { id, by },
531 crate::SystemMessage::UserBanned { id } => Self::UserBanned { id },
532 crate::SystemMessage::UserJoined { id } => Self::UserJoined { id },
533 crate::SystemMessage::UserKicked { id } => Self::UserKicked { id },
534 crate::SystemMessage::UserLeft { id } => Self::UserLeft { id },
535 crate::SystemMessage::UserRemove { id, by } => Self::UserRemove { id, by },
536 crate::SystemMessage::MessagePinned { id, by } => Self::MessagePinned { id, by },
537 crate::SystemMessage::MessageUnpinned { id, by } => Self::MessageUnpinned { id, by },
538 crate::SystemMessage::CallStarted { by, finished_at } => {
539 Self::CallStarted { by, finished_at }
540 }
541 }
542 }
543}
544
545impl From<crate::Interactions> for Interactions {
546 fn from(value: crate::Interactions) -> Self {
547 Interactions {
548 reactions: value
549 .reactions
550 .map(|reactions| reactions.into_iter().collect()),
551 restrict_reactions: value.restrict_reactions,
552 }
553 }
554}
555
556impl From<Interactions> for crate::Interactions {
557 fn from(value: Interactions) -> Self {
558 crate::Interactions {
559 reactions: value
560 .reactions
561 .map(|reactions| reactions.into_iter().collect()),
562 restrict_reactions: value.restrict_reactions,
563 }
564 }
565}
566
567impl From<crate::AppendMessage> for AppendMessage {
568 fn from(value: crate::AppendMessage) -> Self {
569 AppendMessage {
570 embeds: value.embeds,
571 }
572 }
573}
574
575impl From<crate::Masquerade> for Masquerade {
576 fn from(value: crate::Masquerade) -> Self {
577 Masquerade {
578 name: value.name,
579 avatar: value.avatar,
580 colour: value.colour,
581 }
582 }
583}
584
585impl From<Masquerade> for crate::Masquerade {
586 fn from(value: Masquerade) -> Self {
587 crate::Masquerade {
588 name: value.name,
589 avatar: value.avatar,
590 colour: value.colour,
591 }
592 }
593}
594
595impl From<crate::PolicyChange> for PolicyChange {
596 fn from(value: crate::PolicyChange) -> Self {
597 PolicyChange {
598 created_time: value.created_time,
599 effective_time: value.effective_time,
600 description: value.description,
601 url: value.url,
602 }
603 }
604}
605
606impl From<crate::Report> for Report {
607 fn from(value: crate::Report) -> Self {
608 Report {
609 id: value.id,
610 author_id: value.author_id,
611 content: value.content,
612 additional_context: value.additional_context,
613 status: value.status,
614 notes: value.notes,
615 }
616 }
617}
618
619impl From<crate::ServerBan> for ServerBan {
620 fn from(value: crate::ServerBan) -> Self {
621 ServerBan {
622 id: value.id.into(),
623 reason: value.reason,
624 }
625 }
626}
627
628impl From<crate::Member> for Member {
629 fn from(value: crate::Member) -> Self {
630 Member {
631 id: value.id.into(),
632 joined_at: value.joined_at,
633 nickname: value.nickname,
634 avatar: value.avatar.map(|f| f.into()),
635 roles: value.roles,
636 timeout: value.timeout,
637 can_publish: value.can_publish,
638 can_receive: value.can_receive,
639 }
640 }
641}
642
643impl From<Member> for crate::Member {
644 fn from(value: Member) -> crate::Member {
645 crate::Member {
646 id: value.id.into(),
647 joined_at: value.joined_at,
648 nickname: value.nickname,
649 avatar: value.avatar.map(|f| f.into()),
650 roles: value.roles,
651 timeout: value.timeout,
652 can_publish: value.can_publish,
653 can_receive: value.can_receive,
654 }
655 }
656}
657
658impl From<crate::PartialMember> for PartialMember {
659 fn from(value: crate::PartialMember) -> Self {
660 PartialMember {
661 id: value.id.map(|id| id.into()),
662 joined_at: value.joined_at,
663 nickname: value.nickname,
664 avatar: value.avatar.map(|f| f.into()),
665 roles: value.roles,
666 timeout: value.timeout,
667 can_publish: value.can_publish,
668 can_receive: value.can_receive,
669 }
670 }
671}
672
673impl From<PartialMember> for crate::PartialMember {
674 fn from(value: PartialMember) -> crate::PartialMember {
675 crate::PartialMember {
676 id: value.id.map(|id| id.into()),
677 joined_at: value.joined_at,
678 nickname: value.nickname,
679 avatar: value.avatar.map(|f| f.into()),
680 roles: value.roles,
681 timeout: value.timeout,
682 can_publish: value.can_publish,
683 can_receive: value.can_receive,
684 }
685 }
686}
687
688impl From<crate::MemberCompositeKey> for MemberCompositeKey {
689 fn from(value: crate::MemberCompositeKey) -> Self {
690 MemberCompositeKey {
691 server: value.server,
692 user: value.user,
693 }
694 }
695}
696
697impl From<MemberCompositeKey> for crate::MemberCompositeKey {
698 fn from(value: MemberCompositeKey) -> crate::MemberCompositeKey {
699 crate::MemberCompositeKey {
700 server: value.server,
701 user: value.user,
702 }
703 }
704}
705
706impl From<crate::FieldsMember> for FieldsMember {
707 fn from(value: crate::FieldsMember) -> Self {
708 match value {
709 crate::FieldsMember::Avatar => FieldsMember::Avatar,
710 crate::FieldsMember::Nickname => FieldsMember::Nickname,
711 crate::FieldsMember::Roles => FieldsMember::Roles,
712 crate::FieldsMember::Timeout => FieldsMember::Timeout,
713 crate::FieldsMember::CanReceive => FieldsMember::CanReceive,
714 crate::FieldsMember::CanPublish => FieldsMember::CanPublish,
715 crate::FieldsMember::JoinedAt => FieldsMember::JoinedAt,
716 crate::FieldsMember::VoiceChannel => FieldsMember::VoiceChannel,
717 }
718 }
719}
720
721impl From<FieldsMember> for crate::FieldsMember {
722 fn from(value: FieldsMember) -> crate::FieldsMember {
723 match value {
724 FieldsMember::Avatar => crate::FieldsMember::Avatar,
725 FieldsMember::Nickname => crate::FieldsMember::Nickname,
726 FieldsMember::Roles => crate::FieldsMember::Roles,
727 FieldsMember::Timeout => crate::FieldsMember::Timeout,
728 FieldsMember::CanReceive => crate::FieldsMember::CanReceive,
729 FieldsMember::CanPublish => crate::FieldsMember::CanPublish,
730 FieldsMember::JoinedAt => crate::FieldsMember::JoinedAt,
731 FieldsMember::VoiceChannel => crate::FieldsMember::VoiceChannel,
732 }
733 }
734}
735
736impl From<crate::RemovalIntention> for RemovalIntention {
737 fn from(value: crate::RemovalIntention) -> Self {
738 match value {
739 crate::RemovalIntention::Ban => RemovalIntention::Ban,
740 crate::RemovalIntention::Kick => RemovalIntention::Kick,
741 crate::RemovalIntention::Leave => RemovalIntention::Leave,
742 }
743 }
744}
745
746impl From<crate::Server> for Server {
747 fn from(value: crate::Server) -> Self {
748 Server {
749 id: value.id,
750 owner: value.owner,
751 name: value.name,
752 description: value.description,
753 channels: value.channels,
754 categories: value
755 .categories
756 .map(|categories| categories.into_iter().map(|v| v.into()).collect()),
757 system_messages: value.system_messages.map(|v| v.into()),
758 roles: value
759 .roles
760 .into_iter()
761 .map(|(k, v)| (k, v.into()))
762 .collect(),
763 default_permissions: value.default_permissions,
764 icon: value.icon.map(|f| f.into()),
765 banner: value.banner.map(|f| f.into()),
766 flags: value.flags.unwrap_or_default() as u32,
767 nsfw: value.nsfw,
768 analytics: value.analytics,
769 discoverable: value.discoverable,
770 }
771 }
772}
773
774impl From<Server> for crate::Server {
775 fn from(value: Server) -> crate::Server {
776 crate::Server {
777 id: value.id,
778 owner: value.owner,
779 name: value.name,
780 description: value.description,
781 channels: value.channels,
782 categories: value
783 .categories
784 .map(|categories| categories.into_iter().map(|v| v.into()).collect()),
785 system_messages: value.system_messages.map(|v| v.into()),
786 roles: value
787 .roles
788 .into_iter()
789 .map(|(k, v)| (k, v.into()))
790 .collect(),
791 default_permissions: value.default_permissions,
792 icon: value.icon.map(|f| f.into()),
793 banner: value.banner.map(|f| f.into()),
794 flags: Some(value.flags as i32),
795 nsfw: value.nsfw,
796 analytics: value.analytics,
797 discoverable: value.discoverable,
798 }
799 }
800}
801
802impl From<crate::PartialServer> for PartialServer {
803 fn from(value: crate::PartialServer) -> Self {
804 PartialServer {
805 id: value.id,
806 owner: value.owner,
807 name: value.name,
808 description: value.description,
809 channels: value.channels,
810 categories: value
811 .categories
812 .map(|categories| categories.into_iter().map(|v| v.into()).collect()),
813 system_messages: value.system_messages.map(|v| v.into()),
814 roles: value
815 .roles
816 .map(|roles| roles.into_iter().map(|(k, v)| (k, v.into())).collect()),
817 default_permissions: value.default_permissions,
818 icon: value.icon.map(|f| f.into()),
819 banner: value.banner.map(|f| f.into()),
820 flags: value.flags.map(|v| v as u32),
821 nsfw: value.nsfw,
822 analytics: value.analytics,
823 discoverable: value.discoverable,
824 }
825 }
826}
827
828impl From<PartialServer> for crate::PartialServer {
829 fn from(value: PartialServer) -> crate::PartialServer {
830 crate::PartialServer {
831 id: value.id,
832 owner: value.owner,
833 name: value.name,
834 description: value.description,
835 channels: value.channels,
836 categories: value
837 .categories
838 .map(|categories| categories.into_iter().map(|v| v.into()).collect()),
839 system_messages: value.system_messages.map(|v| v.into()),
840 roles: value
841 .roles
842 .map(|roles| roles.into_iter().map(|(k, v)| (k, v.into())).collect()),
843 default_permissions: value.default_permissions,
844 icon: value.icon.map(|f| f.into()),
845 banner: value.banner.map(|f| f.into()),
846 flags: value.flags.map(|v| v as i32),
847 nsfw: value.nsfw,
848 analytics: value.analytics,
849 discoverable: value.discoverable,
850 }
851 }
852}
853
854impl From<crate::FieldsServer> for FieldsServer {
855 fn from(value: crate::FieldsServer) -> Self {
856 match value {
857 crate::FieldsServer::Banner => FieldsServer::Banner,
858 crate::FieldsServer::Categories => FieldsServer::Categories,
859 crate::FieldsServer::Description => FieldsServer::Description,
860 crate::FieldsServer::Icon => FieldsServer::Icon,
861 crate::FieldsServer::SystemMessages => FieldsServer::SystemMessages,
862 }
863 }
864}
865
866impl From<FieldsServer> for crate::FieldsServer {
867 fn from(value: FieldsServer) -> crate::FieldsServer {
868 match value {
869 FieldsServer::Banner => crate::FieldsServer::Banner,
870 FieldsServer::Categories => crate::FieldsServer::Categories,
871 FieldsServer::Description => crate::FieldsServer::Description,
872 FieldsServer::Icon => crate::FieldsServer::Icon,
873 FieldsServer::SystemMessages => crate::FieldsServer::SystemMessages,
874 }
875 }
876}
877
878impl From<crate::Category> for Category {
879 fn from(value: crate::Category) -> Self {
880 Category {
881 id: value.id,
882 title: value.title,
883 channels: value.channels,
884 }
885 }
886}
887
888impl From<Category> for crate::Category {
889 fn from(value: Category) -> Self {
890 crate::Category {
891 id: value.id,
892 title: value.title,
893 channels: value.channels,
894 }
895 }
896}
897
898impl From<crate::SystemMessageChannels> for SystemMessageChannels {
899 fn from(value: crate::SystemMessageChannels) -> Self {
900 SystemMessageChannels {
901 user_joined: value.user_joined,
902 user_left: value.user_left,
903 user_kicked: value.user_kicked,
904 user_banned: value.user_banned,
905 }
906 }
907}
908
909impl From<SystemMessageChannels> for crate::SystemMessageChannels {
910 fn from(value: SystemMessageChannels) -> Self {
911 crate::SystemMessageChannels {
912 user_joined: value.user_joined,
913 user_left: value.user_left,
914 user_kicked: value.user_kicked,
915 user_banned: value.user_banned,
916 }
917 }
918}
919
920impl From<crate::Role> for Role {
921 fn from(value: crate::Role) -> Self {
922 Role {
923 id: value.id,
924 name: value.name,
925 permissions: value.permissions,
926 colour: value.colour,
927 hoist: value.hoist,
928 rank: value.rank,
929 icon: value.icon.map(|f| f.into()),
930 }
931 }
932}
933
934impl From<Role> for crate::Role {
935 fn from(value: Role) -> crate::Role {
936 crate::Role {
937 id: value.id,
938 name: value.name,
939 permissions: value.permissions,
940 colour: value.colour,
941 hoist: value.hoist,
942 rank: value.rank,
943 icon: value.icon.map(|f| f.into()),
944 }
945 }
946}
947
948impl From<crate::PartialRole> for PartialRole {
949 fn from(value: crate::PartialRole) -> Self {
950 PartialRole {
951 id: value.id,
952 name: value.name,
953 permissions: value.permissions,
954 colour: value.colour,
955 hoist: value.hoist,
956 rank: value.rank,
957 icon: value.icon.map(|f| f.into()),
958 }
959 }
960}
961
962impl From<PartialRole> for crate::PartialRole {
963 fn from(value: PartialRole) -> crate::PartialRole {
964 crate::PartialRole {
965 id: value.id,
966 name: value.name,
967 permissions: value.permissions,
968 colour: value.colour,
969 hoist: value.hoist,
970 rank: value.rank,
971 icon: value.icon.map(|f| f.into()),
972 }
973 }
974}
975
976impl From<crate::FieldsRole> for FieldsRole {
977 fn from(value: crate::FieldsRole) -> Self {
978 match value {
979 crate::FieldsRole::Colour => FieldsRole::Colour,
980 crate::FieldsRole::Icon => FieldsRole::Icon,
981 }
982 }
983}
984
985impl From<FieldsRole> for crate::FieldsRole {
986 fn from(value: FieldsRole) -> Self {
987 match value {
988 FieldsRole::Colour => crate::FieldsRole::Colour,
989 FieldsRole::Icon => crate::FieldsRole::Icon,
990 }
991 }
992}
993
994impl crate::User {
995 pub async fn into<'a, P>(self, db: &Database, perspective: P) -> User
996 where
997 P: Into<Option<&'a crate::User>>,
998 {
999 let perspective = perspective.into();
1000 let (relationship, can_see_profile) = if self.bot.is_some() {
1001 (RelationshipStatus::None, true)
1002 } else if let Some(perspective) = perspective {
1003 let mut query = DatabasePermissionQuery::new(db, perspective).user(&self);
1004
1005 if perspective.id == self.id {
1006 (RelationshipStatus::User, true)
1007 } else {
1008 (
1009 perspective
1010 .relations
1011 .as_ref()
1012 .map(|relations| {
1013 relations
1014 .iter()
1015 .find(|relationship| relationship.id == self.id)
1016 .map(|relationship| relationship.status.clone().into())
1017 .unwrap_or_default()
1018 })
1019 .unwrap_or_default(),
1020 calculate_user_permissions(&mut query)
1021 .await
1022 .has_user_permission(UserPermission::ViewProfile),
1023 )
1024 }
1025 } else {
1026 (RelationshipStatus::None, false)
1027 };
1028
1029 let badges = self.get_badges().await;
1030
1031 User {
1032 username: self.username,
1033 discriminator: self.discriminator,
1034 display_name: self.display_name,
1035 avatar: self.avatar.map(|file| file.into()),
1036 relations: if let Some(crate::User { id, .. }) = perspective {
1037 if id == &self.id {
1038 self.relations
1039 .unwrap_or_default()
1040 .into_iter()
1041 .map(|relation| relation.into())
1042 .collect()
1043 } else {
1044 vec![]
1045 }
1046 } else {
1047 vec![]
1048 },
1049 badges,
1050 online: can_see_profile
1051 && revolt_presence::is_online(&self.id).await
1052 && !matches!(
1053 self.status,
1054 Some(crate::UserStatus {
1055 presence: Some(crate::Presence::Invisible),
1056 ..
1057 })
1058 ),
1059 status: if can_see_profile {
1060 self.status.and_then(|status| status.into(true))
1061 } else {
1062 None
1063 },
1064 flags: self.flags.unwrap_or_default() as u32,
1065 privileged: self.privileged,
1066 bot: self.bot.map(|bot| bot.into()),
1067 relationship,
1068 id: self.id,
1069 }
1070 }
1071
1072 pub async fn into_known<'a, P>(self, perspective: P, is_online: bool) -> User
1076 where
1077 P: Into<Option<&'a crate::User>>,
1078 {
1079 let perspective = perspective.into();
1080 let (relationship, can_see_profile) = if self.bot.is_some() {
1081 (RelationshipStatus::None, true)
1082 } else if let Some(perspective) = perspective {
1083 if perspective.id == self.id {
1084 (RelationshipStatus::User, true)
1085 } else {
1086 let relationship = perspective
1087 .relations
1088 .as_ref()
1089 .map(|relations| {
1090 relations
1091 .iter()
1092 .find(|relationship| relationship.id == self.id)
1093 .map(|relationship| relationship.status.clone().into())
1094 .unwrap_or_default()
1095 })
1096 .unwrap_or_default();
1097
1098 let can_see_profile = relationship != RelationshipStatus::BlockedOther;
1099 (relationship, can_see_profile)
1100 }
1101 } else {
1102 (RelationshipStatus::None, false)
1103 };
1104
1105 let badges = self.get_badges().await;
1106
1107 User {
1108 username: self.username,
1109 discriminator: self.discriminator,
1110 display_name: self.display_name,
1111 avatar: self.avatar.map(|file| file.into()),
1112 relations: vec![],
1113 badges,
1114 online: can_see_profile
1115 && is_online
1116 && !matches!(
1117 self.status,
1118 Some(crate::UserStatus {
1119 presence: Some(crate::Presence::Invisible),
1120 ..
1121 })
1122 ),
1123 status: if can_see_profile {
1124 self.status.and_then(|status| status.into(true))
1125 } else {
1126 None
1127 },
1128 flags: self.flags.unwrap_or_default() as u32,
1129 privileged: self.privileged,
1130 bot: self.bot.map(|bot| bot.into()),
1131 relationship,
1132 id: self.id,
1133 }
1134 }
1135
1136 pub async fn into_known_static(self, is_online: bool) -> User {
1138 let badges = self.get_badges().await;
1139
1140 User {
1141 username: self.username,
1142 discriminator: self.discriminator,
1143 display_name: self.display_name,
1144 avatar: self.avatar.map(|file| file.into()),
1145 relations: vec![],
1146 badges,
1147 online: is_online
1148 && !matches!(
1149 self.status,
1150 Some(crate::UserStatus {
1151 presence: Some(crate::Presence::Invisible),
1152 ..
1153 })
1154 ),
1155 status: self.status.and_then(|status| status.into(true)),
1156 flags: self.flags.unwrap_or_default() as u32,
1157 privileged: self.privileged,
1158 bot: self.bot.map(|bot| bot.into()),
1159 relationship: RelationshipStatus::None, id: self.id,
1161 }
1162 }
1163
1164 pub async fn into_self(self, force_online: bool) -> User {
1165 let badges = self.get_badges().await;
1166
1167 User {
1168 username: self.username,
1169 discriminator: self.discriminator,
1170 display_name: self.display_name,
1171 avatar: self.avatar.map(|file| file.into()),
1172 relations: self
1173 .relations
1174 .map(|relationships| {
1175 relationships
1176 .into_iter()
1177 .map(|relationship| relationship.into())
1178 .collect()
1179 })
1180 .unwrap_or_default(),
1181 badges,
1182 online: (force_online || revolt_presence::is_online(&self.id).await)
1183 && !matches!(
1184 self.status,
1185 Some(crate::UserStatus {
1186 presence: Some(crate::Presence::Invisible),
1187 ..
1188 })
1189 ),
1190 status: self.status.and_then(|status| status.into(true)),
1191 flags: self.flags.unwrap_or_default() as u32,
1192 privileged: self.privileged,
1193 bot: self.bot.map(|bot| bot.into()),
1194 relationship: RelationshipStatus::User,
1195 id: self.id,
1196 }
1197 }
1198
1199 pub fn as_author_for_system(&self) -> MessageAuthor {
1200 MessageAuthor::System {
1201 username: &self.username,
1202 avatar: self.avatar.as_ref().map(|file| file.id.as_ref()),
1203 }
1204 }
1205}
1206
1207impl From<User> for crate::User {
1208 fn from(value: User) -> crate::User {
1209 crate::User {
1210 id: value.id,
1211 username: value.username,
1212 discriminator: value.discriminator,
1213 display_name: value.display_name,
1214 avatar: value.avatar.map(Into::into),
1215 relations: None,
1216 badges: Some(value.badges as i32),
1217 status: value.status.map(Into::into),
1218 profile: None,
1219 flags: Some(value.flags as i32),
1220 privileged: value.privileged,
1221 bot: value.bot.map(Into::into),
1222 suspended_until: None,
1223 last_acknowledged_policy_change: Timestamp::UNIX_EPOCH,
1224 }
1225 }
1226}
1227
1228impl From<crate::PartialUser> for PartialUser {
1229 fn from(value: crate::PartialUser) -> Self {
1230 PartialUser {
1231 username: value.username,
1232 discriminator: value.discriminator,
1233 display_name: value.display_name,
1234 avatar: value.avatar.map(|file| file.into()),
1235 relations: value.relations.map(|relationships| {
1236 relationships
1237 .into_iter()
1238 .map(|relationship| relationship.into())
1239 .collect()
1240 }),
1241 badges: value.badges.map(|badges| badges as u32),
1242 status: value.status.and_then(|status| status.into(false)),
1243 flags: value.flags.map(|flags| flags as u32),
1244 privileged: value.privileged,
1245 bot: value.bot.map(|bot| bot.into()),
1246 relationship: None,
1247 online: None,
1248 id: value.id,
1249 }
1250 }
1251}
1252
1253impl From<FieldsUser> for crate::FieldsUser {
1254 fn from(value: FieldsUser) -> Self {
1255 match value {
1256 FieldsUser::Avatar => crate::FieldsUser::Avatar,
1257 FieldsUser::ProfileBackground => crate::FieldsUser::ProfileBackground,
1258 FieldsUser::ProfileContent => crate::FieldsUser::ProfileContent,
1259 FieldsUser::StatusPresence => crate::FieldsUser::StatusPresence,
1260 FieldsUser::StatusText => crate::FieldsUser::StatusText,
1261 FieldsUser::DisplayName => crate::FieldsUser::DisplayName,
1262
1263 FieldsUser::Internal => crate::FieldsUser::None,
1264 }
1265 }
1266}
1267
1268impl From<crate::FieldsUser> for FieldsUser {
1269 fn from(value: crate::FieldsUser) -> Self {
1270 match value {
1271 crate::FieldsUser::Avatar => FieldsUser::Avatar,
1272 crate::FieldsUser::ProfileBackground => FieldsUser::ProfileBackground,
1273 crate::FieldsUser::ProfileContent => FieldsUser::ProfileContent,
1274 crate::FieldsUser::StatusPresence => FieldsUser::StatusPresence,
1275 crate::FieldsUser::StatusText => FieldsUser::StatusText,
1276 crate::FieldsUser::DisplayName => FieldsUser::DisplayName,
1277
1278 crate::FieldsUser::Suspension => FieldsUser::Internal,
1279 crate::FieldsUser::None => FieldsUser::Internal,
1280 }
1281 }
1282}
1283
1284impl From<crate::RelationshipStatus> for RelationshipStatus {
1285 fn from(value: crate::RelationshipStatus) -> Self {
1286 match value {
1287 crate::RelationshipStatus::None => RelationshipStatus::None,
1288 crate::RelationshipStatus::User => RelationshipStatus::User,
1289 crate::RelationshipStatus::Friend => RelationshipStatus::Friend,
1290 crate::RelationshipStatus::Outgoing => RelationshipStatus::Outgoing,
1291 crate::RelationshipStatus::Incoming => RelationshipStatus::Incoming,
1292 crate::RelationshipStatus::Blocked => RelationshipStatus::Blocked,
1293 crate::RelationshipStatus::BlockedOther => RelationshipStatus::BlockedOther,
1294 }
1295 }
1296}
1297
1298impl From<crate::Relationship> for Relationship {
1299 fn from(value: crate::Relationship) -> Self {
1300 Self {
1301 user_id: value.id,
1302 status: value.status.into(),
1303 }
1304 }
1305}
1306
1307impl From<crate::Presence> for Presence {
1308 fn from(value: crate::Presence) -> Self {
1309 match value {
1310 crate::Presence::Online => Presence::Online,
1311 crate::Presence::Idle => Presence::Idle,
1312 crate::Presence::Focus => Presence::Focus,
1313 crate::Presence::Busy => Presence::Busy,
1314 crate::Presence::Invisible => Presence::Invisible,
1315 }
1316 }
1317}
1318
1319impl From<Presence> for crate::Presence {
1320 fn from(value: Presence) -> crate::Presence {
1321 match value {
1322 Presence::Online => crate::Presence::Online,
1323 Presence::Idle => crate::Presence::Idle,
1324 Presence::Focus => crate::Presence::Focus,
1325 Presence::Busy => crate::Presence::Busy,
1326 Presence::Invisible => crate::Presence::Invisible,
1327 }
1328 }
1329}
1330
1331impl crate::UserStatus {
1332 fn into(self, discard_invisible: bool) -> Option<UserStatus> {
1333 let status = UserStatus {
1334 text: self.text,
1335 presence: self.presence.and_then(|presence| {
1336 if discard_invisible && presence == crate::Presence::Invisible {
1337 None
1338 } else {
1339 Some(presence.into())
1340 }
1341 }),
1342 };
1343
1344 if status.text.is_none() && status.presence.is_none() {
1345 None
1346 } else {
1347 Some(status)
1348 }
1349 }
1350}
1351
1352impl From<UserStatus> for crate::UserStatus {
1353 fn from(value: UserStatus) -> crate::UserStatus {
1354 crate::UserStatus {
1355 text: value.text,
1356 presence: value.presence.map(|presence| presence.into()),
1357 }
1358 }
1359}
1360
1361impl From<crate::UserProfile> for UserProfile {
1362 fn from(value: crate::UserProfile) -> Self {
1363 UserProfile {
1364 content: value.content,
1365 background: value.background.map(|file| file.into()),
1366 }
1367 }
1368}
1369
1370impl From<UserProfile> for crate::UserProfile {
1371 fn from(value: UserProfile) -> crate::UserProfile {
1372 crate::UserProfile {
1373 content: value.content,
1374 background: value.background.map(|file| file.into()),
1375 }
1376 }
1377}
1378
1379impl From<crate::BotInformation> for BotInformation {
1380 fn from(value: crate::BotInformation) -> Self {
1381 BotInformation {
1382 owner_id: value.owner,
1383 }
1384 }
1385}
1386
1387impl From<BotInformation> for crate::BotInformation {
1388 fn from(value: BotInformation) -> crate::BotInformation {
1389 crate::BotInformation {
1390 owner: value.owner_id,
1391 }
1392 }
1393}
1394
1395impl From<crate::FieldsMessage> for FieldsMessage {
1396 fn from(value: crate::FieldsMessage) -> Self {
1397 match value {
1398 crate::FieldsMessage::Pinned => FieldsMessage::Pinned,
1399 }
1400 }
1401}
1402impl From<FieldsMessage> for crate::FieldsMessage {
1403 fn from(value: FieldsMessage) -> Self {
1404 match value {
1405 FieldsMessage::Pinned => crate::FieldsMessage::Pinned,
1406 }
1407 }
1408}
1409
1410impl From<VoiceInformation> for crate::VoiceInformation {
1411 fn from(value: VoiceInformation) -> Self {
1412 crate::VoiceInformation {
1413 max_users: value.max_users,
1414 }
1415 }
1416}
1417
1418impl From<crate::VoiceInformation> for VoiceInformation {
1419 fn from(value: crate::VoiceInformation) -> Self {
1420 VoiceInformation {
1421 max_users: value.max_users,
1422 }
1423 }
1424}