use crate::{config::ResourceType, InMemoryCache, UpdateCache};
use std::borrow::Cow;
use twilight_model::{
application::interaction::InteractionData, gateway::payload::incoming::InteractionCreate,
};
impl UpdateCache for InteractionCreate {
fn update(&self, cache: &InMemoryCache) {
if cache.wants(ResourceType::MEMBER) {
if let (Some(member), Some(guild_id)) = (&self.member, self.guild_id) {
if let Some(user) = &member.user {
cache.cache_user(Cow::Borrowed(user), self.guild_id);
cache.cache_borrowed_partial_member(guild_id, member, user.id);
}
}
}
if cache.wants(ResourceType::USER) {
if let Some(user) = &self.user {
cache.cache_user(Cow::Borrowed(user), None);
}
}
if let Some(InteractionData::ApplicationCommand(data)) = &self.data {
if let Some(resolved) = &data.resolved {
for u in resolved.users.values() {
if cache.wants(ResourceType::USER) {
cache.cache_user(Cow::Borrowed(u), self.guild_id);
}
if !cache.wants(ResourceType::MEMBER) || self.guild_id.is_none() {
continue;
}
if let Some((&id, member)) =
&resolved.members.iter().find(|(&id, _)| id == u.id)
{
if let Some(guild_id) = self.guild_id {
cache.cache_borrowed_interaction_member(guild_id, member, id);
}
}
}
if cache.wants(ResourceType::ROLE) {
if let Some(guild_id) = self.guild_id {
cache.cache_roles(guild_id, resolved.roles.values().cloned());
}
}
}
}
}
}
#[cfg(test)]
mod tests {
use crate::InMemoryCache;
use std::collections::HashMap;
use twilight_model::{
application::{
command::CommandType,
interaction::{
application_command::{
CommandData, CommandInteractionDataResolved, InteractionMember,
},
Interaction, InteractionData, InteractionType,
},
},
channel::{
message::{
sticker::{MessageSticker, StickerFormatType},
MessageFlags, MessageType,
},
Message,
},
gateway::payload::incoming::InteractionCreate,
guild::{PartialMember, Permissions, Role},
id::Id,
user::User,
util::{image_hash::ImageHashParseError, ImageHash, Timestamp},
};
#[allow(clippy::too_many_lines)]
#[test]
fn interaction_create() -> Result<(), ImageHashParseError> {
let timestamp = Timestamp::from_secs(1_632_072_645).expect("non zero");
let avatar2 = ImageHash::parse(b"3a43231a99f4dfcf0fd94d1d8defd301")?;
let avatar3 = ImageHash::parse(b"5e23c298295ad37936cfe24ad314774f")?;
let cache = InMemoryCache::new();
cache.update(&InteractionCreate(Interaction {
app_permissions: Some(Permissions::SEND_MESSAGES),
application_id: Id::new(1),
channel_id: Some(Id::new(2)),
data: Some(InteractionData::ApplicationCommand(Box::new(CommandData {
guild_id: None,
id: Id::new(5),
name: "command name".into(),
kind: CommandType::ChatInput, options: Vec::new(),
resolved: Some(CommandInteractionDataResolved {
attachments: HashMap::new(),
channels: HashMap::new(),
members: HashMap::from([(
Id::new(7),
InteractionMember {
avatar: None,
communication_disabled_until: None,
joined_at: timestamp,
nick: None,
pending: false,
permissions: Permissions::empty(),
premium_since: None,
roles: vec![Id::new(8)],
},
)]),
messages: HashMap::from([(
Id::new(4),
Message {
activity: None,
application: None,
application_id: None,
attachments: Vec::new(),
author: User {
accent_color: None,
avatar: Some(avatar3),
banner: None,
bot: false,
discriminator: 1,
email: None,
flags: None,
id: Id::new(3),
locale: None,
mfa_enabled: None,
name: "test".to_owned(),
premium_type: None,
public_flags: None,
system: None,
verified: None,
},
channel_id: Id::new(2),
components: Vec::new(),
content: "ping".to_owned(),
edited_timestamp: None,
embeds: Vec::new(),
flags: Some(MessageFlags::empty()),
guild_id: Some(Id::new(1)),
id: Id::new(4),
interaction: None,
kind: MessageType::Regular,
member: Some(PartialMember {
avatar: None,
communication_disabled_until: None,
deaf: false,
joined_at: timestamp,
mute: false,
nick: Some("member nick".to_owned()),
permissions: None,
premium_since: None,
roles: Vec::new(),
user: None,
}),
mention_channels: Vec::new(),
mention_everyone: false,
mention_roles: Vec::new(),
mentions: Vec::new(),
pinned: false,
reactions: Vec::new(),
reference: None,
sticker_items: vec![MessageSticker {
format_type: StickerFormatType::Png,
id: Id::new(1),
name: "sticker name".to_owned(),
}],
referenced_message: None,
thread: None,
timestamp,
tts: false,
webhook_id: None,
},
)]),
roles: HashMap::from([(
Id::new(8),
Role {
color: 0u32,
hoist: false,
icon: None,
id: Id::new(8),
managed: false,
mentionable: true,
name: "role name".into(),
permissions: Permissions::empty(),
position: 2i64,
tags: None,
unicode_emoji: None,
},
)]),
users: HashMap::from([(
Id::new(7),
User {
accent_color: None,
avatar: Some(avatar2),
banner: None,
bot: false,
discriminator: 5678,
email: None,
flags: None,
id: Id::new(7),
locale: None,
mfa_enabled: None,
name: "different name".into(),
premium_type: None,
public_flags: None,
system: None,
verified: None,
},
)]),
}),
target_id: None,
}))),
guild_id: Some(Id::new(3)),
guild_locale: None,
id: Id::new(4),
kind: InteractionType::ApplicationCommand,
locale: Some("en-GB".to_owned()),
member: Some(PartialMember {
avatar: None,
communication_disabled_until: None,
deaf: false,
joined_at: timestamp,
mute: false,
nick: None,
permissions: Some(Permissions::empty()),
premium_since: None,
roles: Vec::new(),
user: Some(User {
accent_color: None,
avatar: Some(avatar3),
banner: None,
bot: false,
discriminator: 1234,
email: None,
flags: None,
id: Id::new(6),
locale: None,
mfa_enabled: None,
name: "username".into(),
premium_type: None,
public_flags: None,
system: None,
verified: None,
}),
}),
message: None,
token: "token".into(),
user: None,
}));
{
let guild_members = cache.guild_members(Id::new(3)).unwrap();
assert_eq!(guild_members.len(), 2);
}
{
let member = cache.member(Id::new(3), Id::new(6)).unwrap();
let user = cache.user(member.user_id).unwrap();
assert_eq!(user.avatar.as_ref().unwrap(), &avatar3);
}
{
let member = cache.member(Id::new(3), Id::new(7)).unwrap();
let user = cache.user(member.user_id).unwrap();
assert_eq!(user.avatar.as_ref().unwrap(), &avatar2);
}
{
let guild_roles = cache.guild_roles(Id::new(3)).unwrap();
assert_eq!(guild_roles.len(), 1);
}
Ok(())
}
}