revolt_database/util/bridge/
v0.rs

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