From 225965851045375248b2fec9032315280e157743 Mon Sep 17 00:00:00 2001 From: Gnome! Date: Mon, 27 Nov 2023 18:02:47 +0000 Subject: [PATCH] Remove `Context` from `FullEvent` (#2626) --- src/client/dispatch.rs | 186 +++++++++++------------------ src/client/event_handler.rs | 149 +++++++++++------------ src/framework/mod.rs | 12 +- src/framework/standard/mod.rs | 3 +- src/gateway/bridge/shard_runner.rs | 2 +- src/internal/macros.rs | 13 -- 6 files changed, 154 insertions(+), 211 deletions(-) diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs index 6e72475a792..f72e5403c46 100644 --- a/src/client/dispatch.rs +++ b/src/client/dispatch.rs @@ -6,7 +6,7 @@ use tracing::debug; use super::event_handler::{EventHandler, RawEventHandler}; use super::{Context, FullEvent}; #[cfg(feature = "cache")] -use crate::cache::CacheUpdate; +use crate::cache::{Cache, CacheUpdate}; #[cfg(feature = "framework")] use crate::framework::Framework; use crate::internal::tokio::spawn_named; @@ -17,18 +17,34 @@ use crate::model::guild::Member; use crate::model::id::GuildId; #[cfg(feature = "cache")] -fn update_cache(context: &Context, event: &mut E) -> Option { - context.cache.update(event) +macro_rules! if_cache { + ($e:expr) => { + $e + }; } #[cfg(not(feature = "cache"))] -fn update_cache(_: &Context, _: &mut E) -> Option<()> { - None +macro_rules! if_cache { + ($e:expr) => { + None + }; +} + +#[cfg(feature = "cache")] +macro_rules! update_cache { + ($cache:ident, $event:ident) => { + $event.update($cache) + }; +} + +#[cfg(not(feature = "cache"))] +macro_rules! update_cache { + ($cache:ident, $event:ident) => {}; } pub(crate) fn dispatch_model( event: Event, - context: Context, + context: &Context, #[cfg(feature = "framework")] framework: Option>, event_handlers: Vec>, raw_event_handlers: Vec>, @@ -38,25 +54,31 @@ pub(crate) fn dispatch_model( tokio::spawn(async move { raw_handler.raw_event(context, event).await }); } - let full_events = update_cache_with_event(context, event); + let full_events = update_cache_with_event( + #[cfg(feature = "cache")] + &context.cache, + event, + ); + if let Some(events) = full_events { let iter = std::iter::once(events.0).chain(events.1); for handler in event_handlers { for event in iter.clone() { + let context = context.clone(); let handler = Arc::clone(&handler); - spawn_named( - event.snake_case_name(), - async move { event.dispatch(&*handler).await }, - ); + spawn_named(event.snake_case_name(), async move { + event.dispatch(context, &*handler).await; + }); } } #[cfg(feature = "framework")] if let Some(framework) = framework { for event in iter { + let context = context.clone(); let framework = Arc::clone(&framework); spawn_named("dispatch::framework::dispatch", async move { - framework.dispatch(event).await; + framework.dispatch(context, event).await; }); } } @@ -70,324 +92,281 @@ pub(crate) fn dispatch_model( /// /// Can return `None` if an event is unknown. #[cfg_attr(not(feature = "cache"), allow(unused_mut))] -fn update_cache_with_event(ctx: Context, event: Event) -> Option<(FullEvent, Option)> { +fn update_cache_with_event( + #[cfg(feature = "cache")] cache: &Cache, + event: Event, +) -> Option<(FullEvent, Option)> { let mut extra_event = None; let event = match event { Event::CommandPermissionsUpdate(event) => FullEvent::CommandPermissionsUpdate { - ctx, permission: event.permission, }, Event::AutoModRuleCreate(event) => FullEvent::AutoModRuleCreate { - ctx, rule: event.rule, }, Event::AutoModRuleUpdate(event) => FullEvent::AutoModRuleUpdate { - ctx, rule: event.rule, }, Event::AutoModRuleDelete(event) => FullEvent::AutoModRuleDelete { - ctx, rule: event.rule, }, Event::AutoModActionExecution(event) => FullEvent::AutoModActionExecution { - ctx, execution: event.execution, }, Event::ChannelCreate(mut event) => { - update_cache(&ctx, &mut event); + update_cache!(cache, event); let channel = event.channel; if channel.kind == ChannelType::Category { FullEvent::CategoryCreate { - ctx, category: channel, } } else { FullEvent::ChannelCreate { - ctx, channel, } } }, Event::ChannelDelete(mut event) => { - let cached_messages = if_cache!(update_cache(&ctx, &mut event)); + let cached_messages = if_cache!(event.update(cache)); let channel = event.channel; if channel.kind == ChannelType::Category { FullEvent::CategoryDelete { - ctx, category: channel, } } else { FullEvent::ChannelDelete { - ctx, channel, messages: cached_messages, } } }, Event::ChannelPinsUpdate(event) => FullEvent::ChannelPinsUpdate { - ctx, pin: event, }, Event::ChannelUpdate(mut event) => { - let old_channel = if_cache!(event.update(&ctx.cache)); + let old_channel = if_cache!(event.update(cache)); FullEvent::ChannelUpdate { - ctx, old: old_channel, new: event.channel, } }, Event::GuildAuditLogEntryCreate(event) => FullEvent::GuildAuditLogEntryCreate { - ctx, entry: event.entry, guild_id: event.guild_id, }, Event::GuildBanAdd(event) => FullEvent::GuildBanAddition { - ctx, guild_id: event.guild_id, banned_user: event.user, }, Event::GuildBanRemove(event) => FullEvent::GuildBanRemoval { - ctx, guild_id: event.guild_id, unbanned_user: event.user, }, Event::GuildCreate(mut event) => { - let is_new = if_cache!(Some(!ctx.cache.unavailable_guilds.contains(&event.guild.id))); + let is_new = if_cache!(Some(!cache.unavailable_guilds.contains(&event.guild.id))); - update_cache(&ctx, &mut event); + update_cache!(cache, event); #[cfg(feature = "cache")] { - let context = ctx.clone(); - - if context.cache.unavailable_guilds.len() == 0 { - context.cache.unavailable_guilds.shrink_to_fit(); + if cache.unavailable_guilds.len() == 0 { + cache.unavailable_guilds.shrink_to_fit(); let guild_amount = - context.cache.guilds.iter().map(|i| *i.key()).collect::>(); + cache.guilds.iter().map(|i| *i.key()).collect::>(); extra_event = Some(FullEvent::CacheReady { - ctx: context, guilds: guild_amount, }); } } FullEvent::GuildCreate { - ctx, guild: event.guild, is_new, } }, Event::GuildDelete(mut event) => { - let full = if_cache!(update_cache(&ctx, &mut event)); + let full = if_cache!(event.update(cache)); FullEvent::GuildDelete { - ctx, incomplete: event.guild, full, } }, Event::GuildEmojisUpdate(mut event) => { - update_cache(&ctx, &mut event); + update_cache!(cache, event); FullEvent::GuildEmojisUpdate { - ctx, guild_id: event.guild_id, current_state: event.emojis, } }, Event::GuildIntegrationsUpdate(event) => FullEvent::GuildIntegrationsUpdate { - ctx, guild_id: event.guild_id, }, Event::GuildMemberAdd(mut event) => { - update_cache(&ctx, &mut event); + update_cache!(cache, event); FullEvent::GuildMemberAddition { - ctx, new_member: event.member, } }, Event::GuildMemberRemove(mut event) => { - let member = if_cache!(update_cache(&ctx, &mut event)); + let member = if_cache!(event.update(cache)); FullEvent::GuildMemberRemoval { - ctx, guild_id: event.guild_id, user: event.user, member_data_if_available: member, } }, Event::GuildMemberUpdate(mut event) => { - let before = if_cache!(update_cache(&ctx, &mut event)); + let before = if_cache!(event.update(cache)); let after: Option = - if_cache!(ctx.cache.member(event.guild_id, event.user.id).map(|m| m.clone())); + if_cache!(cache.member(event.guild_id, event.user.id).map(|m| m.clone())); FullEvent::GuildMemberUpdate { - ctx, old_if_available: before, new: after, event, } }, Event::GuildMembersChunk(mut event) => { - update_cache(&ctx, &mut event); + update_cache!(cache, event); FullEvent::GuildMembersChunk { - ctx, chunk: event, } }, Event::GuildRoleCreate(mut event) => { - update_cache(&ctx, &mut event); + update_cache!(cache, event); FullEvent::GuildRoleCreate { - ctx, new: event.role, } }, Event::GuildRoleDelete(mut event) => { - let role = if_cache!(update_cache(&ctx, &mut event)); + let role = if_cache!(event.update(cache)); FullEvent::GuildRoleDelete { - ctx, guild_id: event.guild_id, removed_role_id: event.role_id, removed_role_data_if_available: role, } }, Event::GuildRoleUpdate(mut event) => { - let before = if_cache!(update_cache(&ctx, &mut event)); + let before = if_cache!(event.update(cache)); FullEvent::GuildRoleUpdate { - ctx, old_data_if_available: before, new: event.role, } }, Event::GuildStickersUpdate(mut event) => { - update_cache(&ctx, &mut event); + update_cache!(cache, event); FullEvent::GuildStickersUpdate { - ctx, guild_id: event.guild_id, current_state: event.stickers, } }, Event::GuildUpdate(event) => { - let before = if_cache!(ctx.cache.guild(event.guild.id).map(|g| g.clone())); + let before = if_cache!(cache.guild(event.guild.id).map(|g| g.clone())); FullEvent::GuildUpdate { - ctx, old_data_if_available: before, new_data: event.guild, } }, Event::InviteCreate(event) => FullEvent::InviteCreate { - ctx, data: event, }, Event::InviteDelete(event) => FullEvent::InviteDelete { - ctx, data: event, }, Event::MessageCreate(mut event) => { - update_cache(&ctx, &mut event); + update_cache!(cache, event); FullEvent::Message { - ctx, new_message: event.message, } }, Event::MessageDeleteBulk(event) => FullEvent::MessageDeleteBulk { - ctx, channel_id: event.channel_id, multiple_deleted_messages_ids: event.ids, guild_id: event.guild_id, }, Event::MessageDelete(event) => FullEvent::MessageDelete { - ctx, channel_id: event.channel_id, deleted_message_id: event.message_id, guild_id: event.guild_id, }, Event::MessageUpdate(mut event) => { - let before = if_cache!(update_cache(&ctx, &mut event)); - let after = if_cache!(ctx.cache.message(event.channel_id, event.id).map(|m| m.clone())); + let before = if_cache!(event.update(cache)); + let after = if_cache!(cache.message(event.channel_id, event.id).map(|m| m.clone())); FullEvent::MessageUpdate { - ctx, old_if_available: before, new: after, event, } }, Event::PresencesReplace(mut event) => { - update_cache(&ctx, &mut event); + update_cache!(cache, event); FullEvent::PresenceReplace { - ctx, presences: event.presences, } }, Event::PresenceUpdate(mut event) => { - update_cache(&ctx, &mut event); + update_cache!(cache, event); FullEvent::PresenceUpdate { - ctx, new_data: event.presence, } }, Event::ReactionAdd(event) => FullEvent::ReactionAdd { - ctx, add_reaction: event.reaction, }, Event::ReactionRemove(event) => FullEvent::ReactionRemove { - ctx, removed_reaction: event.reaction, }, Event::ReactionRemoveAll(event) => FullEvent::ReactionRemoveAll { - ctx, channel_id: event.channel_id, removed_from_message_id: event.message_id, }, Event::ReactionRemoveEmoji(event) => FullEvent::ReactionRemoveEmoji { - ctx, removed_reactions: event.reaction, }, Event::Ready(mut event) => { - update_cache(&ctx, &mut event); + update_cache!(cache, event); #[cfg(feature = "cache")] { - let mut shards = ctx.cache.shard_data.write(); + let mut shards = cache.shard_data.write(); if shards.connected.len() as u32 == shards.total && !shards.has_sent_shards_ready { shards.has_sent_shards_ready = true; let total = shards.total; drop(shards); extra_event = Some(FullEvent::ShardsReady { - ctx: ctx.clone(), total_shards: total, }); } } FullEvent::Ready { - ctx, data_about_bot: event.ready, } }, Event::Resumed(event) => FullEvent::Resume { - ctx, event, }, Event::TypingStart(event) => FullEvent::TypingStart { - ctx, event, }, Event::Unknown(event) => { @@ -395,32 +374,28 @@ fn update_cache_with_event(ctx: Context, event: Event) -> Option<(FullEvent, Opt return None; }, Event::UserUpdate(mut event) => { - let before = if_cache!(update_cache(&ctx, &mut event)); + let before = if_cache!(event.update(cache)); FullEvent::UserUpdate { - ctx, old_data: before, new: event.current_user, } }, Event::VoiceServerUpdate(event) => FullEvent::VoiceServerUpdate { - ctx, event, }, Event::VoiceStateUpdate(mut event) => { - let before = if_cache!(update_cache(&ctx, &mut event)); + let before = if_cache!(event.update(cache)); FullEvent::VoiceStateUpdate { - ctx, old: before, new: event.voice_state, } }, Event::VoiceChannelStatusUpdate(mut event) => { - let old = if_cache!(update_cache(&ctx, &mut event)); + let old = if_cache!(event.update(cache)); FullEvent::VoiceChannelStatusUpdate { - ctx, old, status: event.status, id: event.id, @@ -429,96 +404,77 @@ fn update_cache_with_event(ctx: Context, event: Event) -> Option<(FullEvent, Opt }, Event::WebhookUpdate(event) => FullEvent::WebhookUpdate { - ctx, guild_id: event.guild_id, belongs_to_channel_id: event.channel_id, }, Event::InteractionCreate(event) => FullEvent::InteractionCreate { - ctx, interaction: event.interaction, }, Event::IntegrationCreate(event) => FullEvent::IntegrationCreate { - ctx, integration: event.integration, }, Event::IntegrationUpdate(event) => FullEvent::IntegrationUpdate { - ctx, integration: event.integration, }, Event::IntegrationDelete(event) => FullEvent::IntegrationDelete { - ctx, integration_id: event.id, guild_id: event.guild_id, application_id: event.application_id, }, Event::StageInstanceCreate(event) => FullEvent::StageInstanceCreate { - ctx, stage_instance: event.stage_instance, }, Event::StageInstanceUpdate(event) => FullEvent::StageInstanceUpdate { - ctx, stage_instance: event.stage_instance, }, Event::StageInstanceDelete(event) => FullEvent::StageInstanceDelete { - ctx, stage_instance: event.stage_instance, }, Event::ThreadCreate(mut event) => { - update_cache(&ctx, &mut event); + update_cache!(cache, event); FullEvent::ThreadCreate { - ctx, thread: event.thread, } }, Event::ThreadUpdate(mut event) => { - let old = if_cache!(update_cache(&ctx, &mut event)); + let old = if_cache!(event.update(cache)); FullEvent::ThreadUpdate { - ctx, old, new: event.thread, } }, Event::ThreadDelete(mut event) => { - let full_thread_data = if_cache!(update_cache(&ctx, &mut event)); + let full_thread_data = if_cache!(event.update(cache)); FullEvent::ThreadDelete { - ctx, thread: event.thread, full_thread_data, } }, Event::ThreadListSync(event) => FullEvent::ThreadListSync { - ctx, thread_list_sync: event, }, Event::ThreadMemberUpdate(event) => FullEvent::ThreadMemberUpdate { - ctx, thread_member: event.member, }, Event::ThreadMembersUpdate(event) => FullEvent::ThreadMembersUpdate { - ctx, thread_members_update: event, }, Event::GuildScheduledEventCreate(event) => FullEvent::GuildScheduledEventCreate { - ctx, event: event.event, }, Event::GuildScheduledEventUpdate(event) => FullEvent::GuildScheduledEventUpdate { - ctx, event: event.event, }, Event::GuildScheduledEventDelete(event) => FullEvent::GuildScheduledEventDelete { - ctx, event: event.event, }, Event::GuildScheduledEventUserAdd(event) => FullEvent::GuildScheduledEventUserAdd { - ctx, subscribed: event, }, Event::GuildScheduledEventUserRemove(event) => FullEvent::GuildScheduledEventUserRemove { - ctx, unsubscribed: event, }, }; diff --git a/src/client/event_handler.rs b/src/client/event_handler.rs index c5b7cd05060..1c34cb26b45 100644 --- a/src/client/event_handler.rs +++ b/src/client/event_handler.rs @@ -14,7 +14,7 @@ macro_rules! event_handler { ( $( $( #[doc = $doc:literal] )* $( #[cfg(feature = $feature:literal)] )? - async fn $method_name:ident(&self, $variant_name:ident { $( + async fn $method_name:ident(&self, $($context:ident: Context,)? | $variant_name:ident { $( $arg_name:ident: $arg_type:ty ),* $(,)? } ); )* ) => { @@ -22,9 +22,9 @@ macro_rules! event_handler { #[async_trait] pub trait EventHandler: Send + Sync { $( $( #[doc = $doc] )* $( #[cfg(feature = $feature)] )? - async fn $method_name(&self, $( $arg_name: $arg_type ),* ) { + async fn $method_name(&self, $($context: Context,)? $( $arg_name: $arg_type ),* ) { // Suppress unused argument warnings - drop(( $( $arg_name ),* )); + drop(( $($context,)? $( $arg_name ),* )); } )* } @@ -59,11 +59,12 @@ macro_rules! event_handler { } /// Runs the given [`EventHandler`]'s code for this event. - pub async fn dispatch(self, handler: &dyn EventHandler) { + pub async fn dispatch(self, ctx: Context, handler: &dyn EventHandler) { match self { $( $( #[cfg(feature = $feature)] )? Self::$variant_name { $( $arg_name ),* } => { - handler.$method_name( $( $arg_name ),* ).await; + $( let $context = ctx; )? + handler.$method_name($($context,)? $( $arg_name ),* ).await; } )* } } @@ -75,27 +76,27 @@ event_handler! { /// Dispatched when the permissions of an application command was updated. /// /// Provides said permission's data. - async fn command_permissions_update(&self, CommandPermissionsUpdate { ctx: Context, permission: CommandPermissions }); + async fn command_permissions_update(&self, ctx: Context, | CommandPermissionsUpdate {permission: CommandPermissions }); /// Dispatched when an auto moderation rule was created. /// /// Provides said rule's data. - async fn auto_moderation_rule_create(&self, AutoModRuleCreate { ctx: Context, rule: Rule }); + async fn auto_moderation_rule_create(&self, ctx: Context, | AutoModRuleCreate { rule: Rule }); /// Dispatched when an auto moderation rule was updated. /// /// Provides said rule's data. - async fn auto_moderation_rule_update(&self, AutoModRuleUpdate { ctx: Context, rule: Rule }); + async fn auto_moderation_rule_update(&self, ctx: Context, | AutoModRuleUpdate { rule: Rule }); /// Dispatched when an auto moderation rule was deleted. /// /// Provides said rule's data. - async fn auto_moderation_rule_delete(&self, AutoModRuleDelete { ctx: Context, rule: Rule }); + async fn auto_moderation_rule_delete(&self, ctx: Context, | AutoModRuleDelete { rule: Rule }); /// Dispatched when an auto moderation rule was triggered and an action was executed. /// /// Provides said action execution's data. - async fn auto_moderation_action_execution(&self, AutoModActionExecution { ctx: Context, execution: ActionExecution }); + async fn auto_moderation_action_execution(&self, ctx: Context, | AutoModActionExecution { execution: ActionExecution }); /// Dispatched when the cache has received and inserted all data from guilds. /// @@ -104,61 +105,61 @@ event_handler! { /// /// Provides the cached guilds' ids. #[cfg(feature = "cache")] - async fn cache_ready(&self, CacheReady { ctx: Context, guilds: Vec }); + async fn cache_ready(&self, ctx: Context, | CacheReady { guilds: Vec }); /// Dispatched when every shard has received a Ready event #[cfg(feature = "cache")] - async fn shards_ready(&self, ShardsReady { ctx: Context, total_shards: u32 }); + async fn shards_ready(&self, ctx: Context, | ShardsReady { total_shards: u32 }); /// Dispatched when a channel is created. /// /// Provides said channel's data. - async fn channel_create(&self, ChannelCreate { ctx: Context, channel: GuildChannel }); + async fn channel_create(&self, ctx: Context, | ChannelCreate { channel: GuildChannel }); /// Dispatched when a category is created. /// /// Provides said category's data. - async fn category_create(&self, CategoryCreate { ctx: Context, category: GuildChannel }); + async fn category_create(&self, ctx: Context, | CategoryCreate { category: GuildChannel }); /// Dispatched when a category is deleted. /// /// Provides said category's data. - async fn category_delete(&self, CategoryDelete { ctx: Context, category: GuildChannel }); + async fn category_delete(&self, ctx: Context, | CategoryDelete { category: GuildChannel }); /// Dispatched when a channel is deleted. /// /// Provides said channel's data. - async fn channel_delete(&self, ChannelDelete { ctx: Context, channel: GuildChannel, messages: Option> }); + async fn channel_delete(&self, ctx: Context, | ChannelDelete { channel: GuildChannel, messages: Option> }); /// Dispatched when a pin is added, deleted. /// /// Provides said pin's data. - async fn channel_pins_update(&self, ChannelPinsUpdate { ctx: Context, pin: ChannelPinsUpdateEvent }); + async fn channel_pins_update(&self, ctx: Context, | ChannelPinsUpdate { pin: ChannelPinsUpdateEvent }); /// Dispatched when a channel is updated. /// /// The old channel data is only provided when the cache feature is enabled. - async fn channel_update(&self, ChannelUpdate { ctx: Context, old: Option, new: GuildChannel }); + async fn channel_update(&self, ctx: Context, | ChannelUpdate { old: Option, new: GuildChannel }); /// Dispatched when a new audit log entry is created. /// /// Provides said entry's data and the id of the guild where it was created. - async fn guild_audit_log_entry_create(&self, GuildAuditLogEntryCreate { ctx: Context, entry: AuditLogEntry, guild_id: GuildId }); + async fn guild_audit_log_entry_create(&self, ctx: Context, | GuildAuditLogEntryCreate { entry: AuditLogEntry, guild_id: GuildId }); /// Dispatched when a user is banned from a guild. /// /// Provides the guild's id and the banned user's data. - async fn guild_ban_addition(&self, GuildBanAddition { ctx: Context, guild_id: GuildId, banned_user: User }); + async fn guild_ban_addition(&self, ctx: Context, | GuildBanAddition { guild_id: GuildId, banned_user: User }); /// Dispatched when a user's ban is lifted from a guild. /// /// Provides the guild's id and the lifted user's data. - async fn guild_ban_removal(&self, GuildBanRemoval { ctx: Context, guild_id: GuildId, unbanned_user: User }); + async fn guild_ban_removal(&self, ctx: Context, | GuildBanRemoval { guild_id: GuildId, unbanned_user: User }); /// Dispatched when a guild is created; or an existing guild's data is sent to us. /// /// Provides the guild's data and whether the guild is new (only when cache feature is enabled). - async fn guild_create(&self, GuildCreate { ctx: Context, guild: Guild, is_new: Option }); + async fn guild_create(&self, ctx: Context, | GuildCreate { guild: Guild, is_new: Option }); /// Dispatched when a guild is deleted. /// @@ -170,19 +171,19 @@ event_handler! { /// flag is true, the guild went offline. /// /// [`unavailable`]: UnavailableGuild::unavailable - async fn guild_delete(&self, GuildDelete { ctx: Context, incomplete: UnavailableGuild, full: Option }); + async fn guild_delete(&self, ctx: Context, | GuildDelete { incomplete: UnavailableGuild, full: Option }); // the emojis were updated. /// Dispatched when the emojis are updated. /// /// Provides the guild's id and the new state of the emojis in the guild. - async fn guild_emojis_update(&self, GuildEmojisUpdate { ctx: Context, guild_id: GuildId, current_state: HashMap }); + async fn guild_emojis_update(&self, ctx: Context, | GuildEmojisUpdate { guild_id: GuildId, current_state: HashMap }); /// Dispatched when a guild's integration is added, updated or removed. /// /// Provides the guild's id. - async fn guild_integrations_update(&self, GuildIntegrationsUpdate { ctx: Context, guild_id: GuildId }); + async fn guild_integrations_update(&self, ctx: Context, | GuildIntegrationsUpdate { guild_id: GuildId }); /// Dispatched when a user joins a guild. /// @@ -190,7 +191,7 @@ event_handler! { /// /// Note: This event will not trigger unless the "guild members" privileged intent is enabled /// on the bot application page. - async fn guild_member_addition(&self, GuildMemberAddition { ctx: Context, new_member: Member }); + async fn guild_member_addition(&self, ctx: Context, | GuildMemberAddition { new_member: Member }); /// Dispatched when a user's membership ends by leaving, getting kicked, or being banned. /// @@ -199,7 +200,7 @@ event_handler! { /// /// Note: This event will not trigger unless the "guild members" privileged intent is enabled /// on the bot application page. - async fn guild_member_removal(&self, GuildMemberRemoval { ctx: Context, guild_id: GuildId, user: User, member_data_if_available: Option }); + async fn guild_member_removal(&self, ctx: Context, | GuildMemberRemoval { guild_id: GuildId, user: User, member_data_if_available: Option }); /// Dispatched when a member is updated (e.g their nickname is updated). /// @@ -208,94 +209,94 @@ event_handler! { /// /// Note: This event will not trigger unless the "guild members" privileged intent is enabled /// on the bot application page. - async fn guild_member_update(&self, GuildMemberUpdate { ctx: Context, old_if_available: Option, new: Option, event: GuildMemberUpdateEvent }); + async fn guild_member_update(&self, ctx: Context, | GuildMemberUpdate { old_if_available: Option, new: Option, event: GuildMemberUpdateEvent }); /// Dispatched when the data for offline members was requested. /// /// Provides the guild's id and the data. - async fn guild_members_chunk(&self, GuildMembersChunk { ctx: Context, chunk: GuildMembersChunkEvent }); + async fn guild_members_chunk(&self, ctx: Context, | GuildMembersChunk { chunk: GuildMembersChunkEvent }); /// Dispatched when a role is created. /// /// Provides the guild's id and the new role's data. - async fn guild_role_create(&self, GuildRoleCreate { ctx: Context, new: Role }); + async fn guild_role_create(&self, ctx: Context, | GuildRoleCreate { new: Role }); /// Dispatched when a role is deleted. /// /// Provides the guild's id, the role's id and its data (if cache feature is enabled and the /// data is available). - async fn guild_role_delete(&self, GuildRoleDelete { ctx: Context, guild_id: GuildId, removed_role_id: RoleId, removed_role_data_if_available: Option }); + async fn guild_role_delete(&self, ctx: Context, | GuildRoleDelete { guild_id: GuildId, removed_role_id: RoleId, removed_role_data_if_available: Option }); /// Dispatched when a role is updated. /// /// Provides the guild's id, the role's old (if cache feature is enabled and the data is /// available) and new data. - async fn guild_role_update(&self, GuildRoleUpdate { ctx: Context, old_data_if_available: Option, new: Role }); + async fn guild_role_update(&self, ctx: Context, | GuildRoleUpdate { old_data_if_available: Option, new: Role }); /// Dispatched when the stickers are updated. /// /// Provides the guild's id and the new state of the stickers in the guild. - async fn guild_stickers_update(&self, GuildStickersUpdate { ctx: Context, guild_id: GuildId, current_state: HashMap }); + async fn guild_stickers_update(&self, ctx: Context, | GuildStickersUpdate { guild_id: GuildId, current_state: HashMap }); /// Dispatched when the guild is updated. /// /// Provides the guild's old data (if cache feature is enabled and the data is available) /// and the new data. - async fn guild_update(&self, GuildUpdate { ctx: Context, old_data_if_available: Option, new_data: PartialGuild }); + async fn guild_update(&self, ctx: Context, | GuildUpdate { old_data_if_available: Option, new_data: PartialGuild }); /// Dispatched when a invite is created. /// /// Provides data about the invite. - async fn invite_create(&self, InviteCreate { ctx: Context, data: InviteCreateEvent }); + async fn invite_create(&self, ctx: Context, | InviteCreate { data: InviteCreateEvent }); /// Dispatched when a invite is deleted. /// /// Provides data about the invite. - async fn invite_delete(&self, InviteDelete { ctx: Context, data: InviteDeleteEvent }); + async fn invite_delete(&self, ctx: Context, | InviteDelete { data: InviteDeleteEvent }); /// Dispatched when a message is created. /// /// Provides the message's data. - async fn message(&self, Message { ctx: Context, new_message: Message }); + async fn message(&self, ctx: Context, | Message { new_message: Message }); /// Dispatched when a message is deleted. /// /// Provides the guild's id, the channel's id and the message's id. - async fn message_delete(&self, MessageDelete { ctx: Context, channel_id: ChannelId, deleted_message_id: MessageId, guild_id: Option }); + async fn message_delete(&self, ctx: Context, | MessageDelete { channel_id: ChannelId, deleted_message_id: MessageId, guild_id: Option }); /// Dispatched when multiple messages were deleted at once. /// /// Provides the guild's id, channel's id and the deleted messages' ids. - async fn message_delete_bulk(&self, MessageDeleteBulk { ctx: Context, channel_id: ChannelId, multiple_deleted_messages_ids: Vec, guild_id: Option }); + async fn message_delete_bulk(&self, ctx: Context, | MessageDeleteBulk { channel_id: ChannelId, multiple_deleted_messages_ids: Vec, guild_id: Option }); /// Dispatched when a message is updated. /// /// Provides the message update data, as well as the actual old and new message if cache /// feature is enabled and the data is available. - async fn message_update(&self, MessageUpdate { ctx: Context, old_if_available: Option, new: Option, event: MessageUpdateEvent }); + async fn message_update(&self, ctx: Context, | MessageUpdate { old_if_available: Option, new: Option, event: MessageUpdateEvent }); /// Dispatched when a new reaction is attached to a message. /// /// Provides the reaction's data. - async fn reaction_add(&self, ReactionAdd { ctx: Context, add_reaction: Reaction }); + async fn reaction_add(&self, ctx: Context, | ReactionAdd { add_reaction: Reaction }); /// Dispatched when a reaction is detached from a message. /// /// Provides the reaction's data. - async fn reaction_remove(&self, ReactionRemove { ctx: Context, removed_reaction: Reaction }); + async fn reaction_remove(&self, ctx: Context, | ReactionRemove { removed_reaction: Reaction }); /// Dispatched when all reactions of a message are detached from a message. /// /// Provides the channel's id and the message's id. - async fn reaction_remove_all(&self, ReactionRemoveAll { ctx: Context, channel_id: ChannelId, removed_from_message_id: MessageId }); + async fn reaction_remove_all(&self, ctx: Context, | ReactionRemoveAll { channel_id: ChannelId, removed_from_message_id: MessageId }); /// Dispatched when all reactions of a message are detached from a message. /// /// Provides the channel's id and the message's id. - async fn reaction_remove_emoji(&self, ReactionRemoveEmoji { ctx: Context, removed_reactions: Reaction }); + async fn reaction_remove_emoji(&self, ctx: Context, | ReactionRemoveEmoji { removed_reactions: Reaction }); /// This event is legacy, and likely no longer sent by discord. - async fn presence_replace(&self, PresenceReplace { ctx: Context, presences: Vec }); + async fn presence_replace(&self, ctx: Context, | PresenceReplace { presences: Vec }); /// Dispatched when a user's presence is updated (e.g off -> on). /// @@ -303,111 +304,111 @@ event_handler! { /// /// Note: This event will not trigger unless the "guild presences" privileged intent is enabled /// on the bot application page. - async fn presence_update(&self, PresenceUpdate { ctx: Context, new_data: Presence }); + async fn presence_update(&self, ctx: Context, | PresenceUpdate { new_data: Presence }); /// Dispatched upon startup. /// /// Provides data about the bot and the guilds it's in. - async fn ready(&self, Ready { ctx: Context, data_about_bot: Ready }); + async fn ready(&self, ctx: Context, | Ready { data_about_bot: Ready }); /// Dispatched upon reconnection. - async fn resume(&self, Resume { ctx: Context, event: ResumedEvent }); + async fn resume(&self, ctx: Context, | Resume { event: ResumedEvent }); /// Dispatched when a shard's connection stage is updated /// /// Provides the context of the shard and the event information about the update. - async fn shard_stage_update(&self, ShardStageUpdate { ctx: Context, event: ShardStageUpdateEvent }); + async fn shard_stage_update(&self, ctx: Context, | ShardStageUpdate { event: ShardStageUpdateEvent }); /// Dispatched when a user starts typing. - async fn typing_start(&self, TypingStart { ctx: Context, event: TypingStartEvent }); + async fn typing_start(&self, ctx: Context, | TypingStart { event: TypingStartEvent }); /// Dispatched when the bot's data is updated. /// /// Provides the old (if cache feature is enabled and the data is available) and new data. - async fn user_update(&self, UserUpdate { ctx: Context, old_data: Option, new: CurrentUser }); + async fn user_update(&self, ctx: Context, | UserUpdate { old_data: Option, new: CurrentUser }); /// Dispatched when a guild's voice server was updated (or changed to another one). /// /// Provides the voice server's data. - async fn voice_server_update(&self, VoiceServerUpdate { ctx: Context, event: VoiceServerUpdateEvent }); + async fn voice_server_update(&self, ctx: Context, | VoiceServerUpdate { event: VoiceServerUpdateEvent }); /// Dispatched when a user joins, leaves or moves to a voice channel. /// /// Provides the guild's id (if available) and the old state (if cache feature is enabled and /// [`GatewayIntents::GUILDS`] is enabled) and the new state of the guild's voice channels. - async fn voice_state_update(&self, VoiceStateUpdate { ctx: Context, old: Option, new: VoiceState }); + async fn voice_state_update(&self, ctx: Context, | VoiceStateUpdate { old: Option, new: VoiceState }); /// Dispatched when a voice channel's status is updated. /// /// Provides the status, channel's id and the guild's id. - async fn voice_channel_status_update(&self, VoiceChannelStatusUpdate { ctx: Context, old: Option, status: Option, id: ChannelId, guild_id: GuildId }); + async fn voice_channel_status_update(&self, ctx: Context, | VoiceChannelStatusUpdate { old: Option, status: Option, id: ChannelId, guild_id: GuildId }); /// Dispatched when a guild's webhook is updated. /// /// Provides the guild's id and the channel's id the webhook belongs in. - async fn webhook_update(&self, WebhookUpdate { ctx: Context, guild_id: GuildId, belongs_to_channel_id: ChannelId }); + async fn webhook_update(&self, ctx: Context, | WebhookUpdate { guild_id: GuildId, belongs_to_channel_id: ChannelId }); /// Dispatched when an interaction is created (e.g a slash command was used or a button was clicked). /// /// Provides the created interaction. - async fn interaction_create(&self, InteractionCreate { ctx: Context, interaction: Interaction }); + async fn interaction_create(&self, ctx: Context, | InteractionCreate { interaction: Interaction }); /// Dispatched when a guild integration is created. /// /// Provides the created integration. - async fn integration_create(&self, IntegrationCreate { ctx: Context, integration: Integration }); + async fn integration_create(&self, ctx: Context, | IntegrationCreate { integration: Integration }); /// Dispatched when a guild integration is updated. /// /// Provides the updated integration. - async fn integration_update(&self, IntegrationUpdate { ctx: Context, integration: Integration }); + async fn integration_update(&self, ctx: Context, | IntegrationUpdate { integration: Integration }); /// Dispatched when a guild integration is deleted. /// /// Provides the integration's id, the id of the guild it belongs to, and its associated application id - async fn integration_delete(&self, IntegrationDelete { ctx: Context, integration_id: IntegrationId, guild_id: GuildId, application_id: Option }); + async fn integration_delete(&self, ctx: Context, | IntegrationDelete { integration_id: IntegrationId, guild_id: GuildId, application_id: Option }); /// Dispatched when a stage instance is created. /// /// Provides the created stage instance. - async fn stage_instance_create(&self, StageInstanceCreate { ctx: Context, stage_instance: StageInstance }); + async fn stage_instance_create(&self, ctx: Context, | StageInstanceCreate { stage_instance: StageInstance }); /// Dispatched when a stage instance is updated. /// /// Provides the updated stage instance. - async fn stage_instance_update(&self, StageInstanceUpdate { ctx: Context, stage_instance: StageInstance }); + async fn stage_instance_update(&self, ctx: Context, | StageInstanceUpdate { stage_instance: StageInstance }); /// Dispatched when a stage instance is deleted. /// /// Provides the deleted stage instance. - async fn stage_instance_delete(&self, StageInstanceDelete { ctx: Context, stage_instance: StageInstance }); + async fn stage_instance_delete(&self, ctx: Context, | StageInstanceDelete { stage_instance: StageInstance }); /// Dispatched when a thread is created or the current user is added to a private thread. /// /// Provides the thread. - async fn thread_create(&self, ThreadCreate { ctx: Context, thread: GuildChannel }); + async fn thread_create(&self, ctx: Context, | ThreadCreate { thread: GuildChannel }); /// Dispatched when a thread is updated. /// /// Provides the updated thread and the old thread data, provided the thread was cached prior to dispatch. - async fn thread_update(&self, ThreadUpdate { ctx: Context, old: Option, new: GuildChannel }); + async fn thread_update(&self, ctx: Context, | ThreadUpdate { old: Option, new: GuildChannel }); /// Dispatched when a thread is deleted. /// /// Provides the partial data about the deleted thread and, if it was present in the cache /// before its deletion, its full data. - async fn thread_delete(&self, ThreadDelete { ctx: Context, thread: PartialGuildChannel, full_thread_data: Option }); + async fn thread_delete(&self, ctx: Context, | ThreadDelete { thread: PartialGuildChannel, full_thread_data: Option }); /// Dispatched when the current user gains access to a channel. /// /// Provides the threads the current user can access, the thread members, the guild Id, and the /// channel Ids of the parent channels being synced. - async fn thread_list_sync(&self, ThreadListSync { ctx: Context, thread_list_sync: ThreadListSyncEvent }); + async fn thread_list_sync(&self, ctx: Context, | ThreadListSync { thread_list_sync: ThreadListSyncEvent }); /// Dispatched when the [`ThreadMember`] for the current user is updated. /// /// Provides the updated thread member. - async fn thread_member_update(&self, ThreadMemberUpdate { ctx: Context, thread_member: ThreadMember }); + async fn thread_member_update(&self, ctx: Context, | ThreadMemberUpdate { thread_member: ThreadMember }); /// Dispatched when anyone is added to or removed from a thread. If the current user does not /// have the [`GatewayIntents::GUILDS`], then this event will only be sent if the current user @@ -417,35 +418,35 @@ event_handler! { /// the thread Id and its guild Id. /// /// [`GatewayIntents::GUILDS`]: crate::model::gateway::GatewayIntents::GUILDS - async fn thread_members_update(&self, ThreadMembersUpdate { ctx: Context, thread_members_update: ThreadMembersUpdateEvent }); + async fn thread_members_update(&self, ctx: Context, | ThreadMembersUpdate { thread_members_update: ThreadMembersUpdateEvent }); /// Dispatched when a scheduled event is created. /// /// Provides data about the scheduled event. - async fn guild_scheduled_event_create(&self, GuildScheduledEventCreate { ctx: Context, event: ScheduledEvent }); + async fn guild_scheduled_event_create(&self, ctx: Context, | GuildScheduledEventCreate { event: ScheduledEvent }); /// Dispatched when a scheduled event is updated. /// /// Provides data about the scheduled event. - async fn guild_scheduled_event_update(&self, GuildScheduledEventUpdate { ctx: Context, event: ScheduledEvent }); + async fn guild_scheduled_event_update(&self, ctx: Context, | GuildScheduledEventUpdate { event: ScheduledEvent }); /// Dispatched when a scheduled event is deleted. /// /// Provides data about the scheduled event. - async fn guild_scheduled_event_delete(&self, GuildScheduledEventDelete { ctx: Context, event: ScheduledEvent }); + async fn guild_scheduled_event_delete(&self, ctx: Context, | GuildScheduledEventDelete { event: ScheduledEvent }); /// Dispatched when a guild member has subscribed to a scheduled event. /// /// Provides data about the subscription. - async fn guild_scheduled_event_user_add(&self, GuildScheduledEventUserAdd { ctx: Context, subscribed: GuildScheduledEventUserAddEvent }); + async fn guild_scheduled_event_user_add(&self, ctx: Context, | GuildScheduledEventUserAdd { subscribed: GuildScheduledEventUserAddEvent }); /// Dispatched when a guild member has unsubscribed from a scheduled event. /// /// Provides data about the cancelled subscription. - async fn guild_scheduled_event_user_remove(&self, GuildScheduledEventUserRemove { ctx: Context, unsubscribed: GuildScheduledEventUserRemoveEvent }); + async fn guild_scheduled_event_user_remove(&self, ctx: Context, | GuildScheduledEventUserRemove { unsubscribed: GuildScheduledEventUserRemoveEvent }); /// Dispatched when an HTTP rate limit is hit - async fn ratelimit(&self, Ratelimit { data: RatelimitInfo }); + async fn ratelimit(&self, | Ratelimit { data: RatelimitInfo }); } /// This core trait for handling raw events diff --git a/src/framework/mod.rs b/src/framework/mod.rs index fce8ff177a1..4580ea292cb 100644 --- a/src/framework/mod.rs +++ b/src/framework/mod.rs @@ -86,7 +86,7 @@ use async_trait::async_trait; #[cfg(feature = "standard_framework")] pub use self::standard::StandardFramework; -use crate::client::{Client, FullEvent}; +use crate::client::{Client, Context, FullEvent}; /// A trait for defining your own framework for serenity to use. /// @@ -101,7 +101,7 @@ pub trait Framework: Send + Sync { let _: &Client = client; } /// Called on every incoming event. - async fn dispatch(&self, event: FullEvent); + async fn dispatch(&self, ctx: Context, event: FullEvent); } #[async_trait] @@ -112,8 +112,8 @@ where async fn init(&mut self, client: &Client) { (**self).init(client).await; } - async fn dispatch(&self, event: FullEvent) { - (**self).dispatch(event).await; + async fn dispatch(&self, ctx: Context, event: FullEvent) { + (**self).dispatch(ctx, event).await; } } @@ -125,7 +125,7 @@ where async fn init(&mut self, client: &Client) { (**self).init(client).await; } - async fn dispatch(&self, event: FullEvent) { - (**self).dispatch(event).await; + async fn dispatch(&self, ctx: Context, event: FullEvent) { + (**self).dispatch(ctx, event).await; } } diff --git a/src/framework/standard/mod.rs b/src/framework/standard/mod.rs index bbb55af8853..8421be1507c 100644 --- a/src/framework/standard/mod.rs +++ b/src/framework/standard/mod.rs @@ -603,9 +603,8 @@ impl StandardFramework { #[async_trait] impl Framework for StandardFramework { #[instrument(skip(self, event))] - async fn dispatch(&self, event: FullEvent) { + async fn dispatch(&self, mut ctx: Context, event: FullEvent) { let FullEvent::Message { - mut ctx, new_message: msg, } = event else { diff --git a/src/gateway/bridge/shard_runner.rs b/src/gateway/bridge/shard_runner.rs index 2ebdefc8bfc..b349ee61ed1 100644 --- a/src/gateway/bridge/shard_runner.rs +++ b/src/gateway/bridge/shard_runner.rs @@ -168,7 +168,7 @@ impl ShardRunner { dispatch_model( event, - self.make_context(), + &self.make_context(), #[cfg(feature = "framework")] self.framework.clone(), self.event_handlers.clone(), diff --git a/src/internal/macros.rs b/src/internal/macros.rs index f51faae0e98..5f46eb53260 100644 --- a/src/internal/macros.rs +++ b/src/internal/macros.rs @@ -27,19 +27,6 @@ macro_rules! status { }; } -#[cfg(all(feature = "cache", feature = "client"))] -macro_rules! if_cache { - ($e:expr) => { - $e - }; -} - -#[cfg(all(not(feature = "cache"), feature = "client"))] -macro_rules! if_cache { - ($e:expr) => { - None - }; -} /// The `enum_number!` macro generates `From` implementations to convert between values and the /// enum which can then be utilized by `serde` with `#[serde(from = "u8", into = "u8")]`. ///