use crate::model::member::ComputedInteractionMember;
use std::fmt::Debug;
use twilight_model::{
application::interaction::InteractionMember,
channel::{
Channel, ChannelType, Message, StageInstance,
message::{Reaction, Sticker},
},
gateway::{
payload::incoming::{GuildUpdate, MemberUpdate},
presence::Presence,
},
guild::{
Emoji, Guild, GuildIntegration, Member, PartialMember, Role,
scheduled_event::GuildScheduledEvent,
},
id::{
Id,
marker::{
ChannelMarker, GuildMarker, RoleMarker, ScheduledEventMarker, StickerMarker, UserMarker,
},
},
user::{CurrentUser, User},
util::{ImageHash, Timestamp},
voice::VoiceState,
};
#[cfg(feature = "permission-calculator")]
use twilight_model::{channel::permission_overwrite::PermissionOverwrite, guild::Permissions};
pub trait CacheableModels: Clone + Debug {
type Channel: CacheableChannel;
type CurrentUser: CacheableCurrentUser;
type Emoji: CacheableEmoji;
type Guild: CacheableGuild;
type GuildIntegration: CacheableGuildIntegration;
type GuildScheduledEvent: CacheableGuildScheduledEvent;
type Member: CacheableMember;
type Message: CacheableMessage;
type Presence: CacheablePresence;
type Role: CacheableRole;
type StageInstance: CacheableStageInstance;
type Sticker: CacheableSticker;
type User: CacheableUser;
type VoiceState: CacheableVoiceState;
}
pub trait CacheableMember:
From<Member>
+ From<ComputedInteractionMember>
+ From<(Id<UserMarker>, PartialMember)>
+ PartialEq<Member>
+ PartialEq<PartialMember>
+ PartialEq<InteractionMember>
+ PartialEq<Self>
+ Clone
+ Debug
{
fn roles(&self) -> &[Id<RoleMarker>];
#[cfg(feature = "permission-calculator")]
fn communication_disabled_until(&self) -> Option<Timestamp>;
fn avatar(&self) -> Option<ImageHash>;
fn deaf(&self) -> Option<bool>;
fn mute(&self) -> Option<bool>;
fn update_with_member_update(&mut self, member_update: &MemberUpdate);
}
pub trait CacheableRole: From<Role> + PartialEq<Role> + PartialEq<Self> + Clone + Debug {
fn position(&self) -> i64;
fn id(&self) -> Id<RoleMarker>;
#[cfg(feature = "permission-calculator")]
fn permissions(&self) -> Permissions;
}
impl CacheableRole for Role {
fn position(&self) -> i64 {
self.position
}
fn id(&self) -> Id<RoleMarker> {
self.id
}
#[cfg(feature = "permission-calculator")]
fn permissions(&self) -> Permissions {
self.permissions
}
}
pub trait CacheableChannel:
From<Channel> + PartialEq<Channel> + PartialEq<Self> + Clone + Debug
{
fn guild_id(&self) -> Option<Id<GuildMarker>>;
fn kind(&self) -> ChannelType;
#[cfg(feature = "permission-calculator")]
fn parent_id(&self) -> Option<Id<ChannelMarker>>;
fn id(&self) -> Id<ChannelMarker>;
#[cfg(feature = "permission-calculator")]
fn permission_overwrites(&self) -> Option<&[PermissionOverwrite]>;
fn set_last_pin_timestamp(&mut self, timestamp: Option<Timestamp>);
}
impl CacheableChannel for Channel {
fn guild_id(&self) -> Option<Id<GuildMarker>> {
self.guild_id
}
fn kind(&self) -> ChannelType {
self.kind
}
#[cfg(feature = "permission-calculator")]
fn parent_id(&self) -> Option<Id<ChannelMarker>> {
self.parent_id
}
fn id(&self) -> Id<ChannelMarker> {
self.id
}
#[cfg(feature = "permission-calculator")]
fn permission_overwrites(&self) -> Option<&[PermissionOverwrite]> {
self.permission_overwrites.as_deref()
}
fn set_last_pin_timestamp(&mut self, timestamp: Option<Timestamp>) {
self.last_pin_timestamp = timestamp;
}
}
pub trait CacheableGuild: From<Guild> + PartialEq<Guild> + PartialEq<Self> + Clone + Debug {
fn id(&self) -> Id<GuildMarker>;
#[cfg(feature = "permission-calculator")]
fn owner_id(&self) -> Id<UserMarker>;
fn set_unavailable(&mut self, unavailable: Option<bool>);
fn update_with_guild_update(&mut self, guild_update: &GuildUpdate);
fn increase_member_count(&mut self, amount: u64);
fn decrease_member_count(&mut self, amount: u64);
}
pub trait CacheableVoiceState:
From<(Id<ChannelMarker>, Id<GuildMarker>, VoiceState)>
+ PartialEq<VoiceState>
+ PartialEq<Self>
+ Clone
+ Debug
{
fn channel_id(&self) -> Id<ChannelMarker>;
}
pub trait CacheableMessage:
From<Message> + PartialEq<Message> + PartialEq<Self> + Clone + Debug
{
fn reactions(&self) -> &[Reaction];
fn reactions_mut(&mut self) -> &mut [Reaction];
fn retain_reactions(&mut self, f: impl FnMut(&Reaction) -> bool);
fn clear_reactions(&mut self);
fn add_reaction(&mut self, reaction: Reaction);
fn remove_reaction(&mut self, idx: usize);
}
pub trait CacheableCurrentUser:
From<CurrentUser> + PartialEq<CurrentUser> + PartialEq<Self> + Clone + Debug
{
fn id(&self) -> Id<UserMarker>;
}
impl CacheableCurrentUser for CurrentUser {
fn id(&self) -> Id<UserMarker> {
self.id
}
}
pub trait CacheableSticker:
From<Sticker> + PartialEq<Sticker> + PartialEq<Self> + Clone + Debug
{
fn id(&self) -> Id<StickerMarker>;
}
pub trait CacheableEmoji: From<Emoji> + PartialEq<Emoji> + PartialEq<Self> + Clone + Debug {}
pub trait CacheableGuildIntegration:
From<GuildIntegration> + PartialEq<GuildIntegration> + PartialEq<Self> + Clone + Debug
{
}
impl CacheableGuildIntegration for GuildIntegration {}
pub trait CacheablePresence:
From<Presence> + PartialEq<Presence> + PartialEq<Self> + Clone + Debug
{
}
pub trait CacheableStageInstance:
From<StageInstance> + PartialEq<StageInstance> + PartialEq<Self> + Clone + Debug
{
}
impl CacheableStageInstance for StageInstance {}
pub trait CacheableUser: From<User> + PartialEq<User> + PartialEq<Self> + Clone + Debug {}
impl CacheableUser for User {}
pub trait CacheableGuildScheduledEvent:
From<GuildScheduledEvent> + PartialEq<GuildScheduledEvent> + PartialEq<Self> + Clone + Debug
{
fn add_user(
&mut self,
guild_id: Id<GuildMarker>,
event_id: Id<ScheduledEventMarker>,
user_id: Id<UserMarker>,
);
fn remove_user(
&mut self,
guild_id: Id<GuildMarker>,
event_id: Id<ScheduledEventMarker>,
user_id: Id<UserMarker>,
);
}
impl CacheableGuildScheduledEvent for GuildScheduledEvent {
fn add_user(
&mut self,
_guild_id: Id<GuildMarker>,
_event_id: Id<ScheduledEventMarker>,
_user_id: Id<UserMarker>,
) {
self.user_count = self.user_count.map(|count| count.saturating_add(1));
}
fn remove_user(
&mut self,
_guild_id: Id<GuildMarker>,
_event_id: Id<ScheduledEventMarker>,
_user_id: Id<UserMarker>,
) {
self.user_count = self.user_count.map(|count| count.saturating_sub(1));
}
}