Skip to content

Commit

Permalink
Factor out collector methods into traits
Browse files Browse the repository at this point in the history
  • Loading branch information
mkrasnitski committed Nov 22, 2024
1 parent 2369544 commit 9e3d21b
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 155 deletions.
6 changes: 3 additions & 3 deletions examples/e09_collectors/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::collections::HashSet;
use std::time::Duration;

use serenity::async_trait;
use serenity::collector::MessageCollector;
use serenity::collector::{CollectMessages, CollectReactions, MessageCollector};
// Collectors are streams, that means we can use `StreamExt` and `TryStreamExt`.
use serenity::futures::stream::StreamExt;
use serenity::model::prelude::*;
Expand All @@ -27,7 +27,7 @@ impl EventHandler for Handler {
// return a builder that can be turned into a Stream, or here, where we can await a
// single reply
let collector =
msg.author.id.await_reply(ctx.shard.clone()).timeout(Duration::from_secs(10));
msg.author.id.collect_messages(ctx.shard.clone()).timeout(Duration::from_secs(10));
if let Some(answer) = collector.await {
if answer.content.to_lowercase() == "ferris" {
let _ = answer.reply(&ctx.http, "That's correct!").await;
Expand All @@ -47,7 +47,7 @@ impl EventHandler for Handler {
// The message model can also be turned into a Collector to collect reactions on it.
let collector = react_msg
.id
.await_reaction(ctx.shard.clone())
.collect_reactions(ctx.shard.clone())
.timeout(Duration::from_secs(10))
.author_id(msg.author.id);

Expand Down
5 changes: 3 additions & 2 deletions examples/e14_message_components/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use serenity::builder::{
CreateSelectMenuKind,
CreateSelectMenuOption,
};
use serenity::collector::CollectComponentInteractions;
use serenity::futures::StreamExt;
use serenity::model::prelude::*;
use serenity::prelude::*;
Expand Down Expand Up @@ -59,7 +60,7 @@ impl EventHandler for Handler {
// manually in the EventHandler.
let interaction = match m
.id
.await_component_interaction(ctx.shard.clone())
.collect_component_interactions(ctx.shard.clone())
.timeout(Duration::from_secs(60 * 3))
.await
{
Expand Down Expand Up @@ -107,7 +108,7 @@ impl EventHandler for Handler {

// Wait for multiple interactions
let mut interaction_stream =
m.id.await_component_interaction(ctx.shard.clone())
m.id.collect_component_interactions(ctx.shard.clone())
.timeout(Duration::from_secs(60 * 3))
.stream();

Expand Down
3 changes: 2 additions & 1 deletion examples/testing/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::borrow::Cow;

use serenity::builder::*;
use serenity::collector::CollectComponentInteractions;
use serenity::model::prelude::*;
use serenity::prelude::*;

Expand Down Expand Up @@ -121,7 +122,7 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> {
.await?;
let button_press = msg
.id
.await_component_interaction(ctx.shard.clone())
.collect_component_interactions(ctx.shard.clone())
.timeout(std::time::Duration::from_secs(10))
.await;
match button_press {
Expand Down
21 changes: 20 additions & 1 deletion src/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ macro_rules! make_specific_collector {
(
$( #[ $($meta:tt)* ] )*
$collector_type:ident, $item_type:ident,
$collector_trait:ident, $method_name:ident,
$extractor:pat => $extracted_item:ident,
$( $filter_name:ident: $filter_type:ty => $filter_passes:expr, )*
) => {
Expand Down Expand Up @@ -100,7 +101,7 @@ macro_rules! make_specific_collector {
let filters_pass = move |$extracted_item: &$item_type| {
// Check each of the built-in filters (author_id, channel_id, etc.)
$( if let Some($filter_name) = &self.$filter_name {
if !$filter_passes {
if !($filter_passes) {
return false;
}
} )*
Expand Down Expand Up @@ -142,12 +143,27 @@ macro_rules! make_specific_collector {
Box::pin(self.next())
}
}

pub trait $collector_trait {
fn $method_name(self, shard_messenger: ShardMessenger) -> $collector_type;
}

$(
impl $collector_trait for $filter_type {
fn $method_name(self, shard_messenger: ShardMessenger) -> $collector_type {
$collector_type::new(shard_messenger).$filter_name(self)
}
}
)*
};
}

make_specific_collector!(
// First line has name of the collector type, and the type of the collected items.
ComponentInteractionCollector, ComponentInteraction,
// Second line has name of the specific trait and method name that will be
// implemented on the filter argument types listed below.
CollectComponentInteractions, collect_component_interactions,
// This defines the extractor pattern, which extracts the data we want to collect from an Event.
Event::InteractionCreate(InteractionCreateEvent {
interaction: Interaction::Component(interaction),
Expand All @@ -165,6 +181,7 @@ make_specific_collector!(
);
make_specific_collector!(
ModalInteractionCollector, ModalInteraction,
CollectModalInteractions, collect_modal_interactions,
Event::InteractionCreate(InteractionCreateEvent {
interaction: Interaction::Modal(interaction),
}) => interaction,
Expand All @@ -176,6 +193,7 @@ make_specific_collector!(
);
make_specific_collector!(
ReactionCollector, Reaction,
CollectReactions, collect_reactions,
Event::ReactionAdd(ReactionAddEvent { reaction }) => reaction,
author_id: UserId => reaction.user_id.map_or(true, |a| a == *author_id),
channel_id: ChannelId => reaction.channel_id == *channel_id,
Expand All @@ -184,6 +202,7 @@ make_specific_collector!(
);
make_specific_collector!(
MessageCollector, Message,
CollectMessages, collect_messages,
Event::MessageCreate(MessageCreateEvent { message }) => message,
author_id: UserId => message.author.id == *author_id,
channel_id: ChannelId => message.channel_id == *channel_id,
Expand Down
30 changes: 0 additions & 30 deletions src/model/channel/channel_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ use crate::builder::{
};
#[cfg(all(feature = "cache", feature = "model"))]
use crate::cache::Cache;
#[cfg(feature = "collector")]
use crate::collector::{MessageCollector, ReactionCollector};
#[cfg(feature = "collector")]
use crate::gateway::ShardMessenger;
#[cfg(feature = "model")]
use crate::http::{CacheHttp, Http, Typing};
use crate::model::prelude::*;
Expand Down Expand Up @@ -802,32 +798,6 @@ impl ChannelId {
builder.execute(http, self).await
}

/// Returns a builder which can be awaited to obtain a message or stream of messages in this
/// channel.
#[cfg(feature = "collector")]
pub fn await_reply(self, shard_messenger: ShardMessenger) -> MessageCollector {
MessageCollector::new(shard_messenger).channel_id(self)
}

/// Same as [`Self::await_reply`].
#[cfg(feature = "collector")]
pub fn await_replies(self, shard_messenger: ShardMessenger) -> MessageCollector {
self.await_reply(shard_messenger)
}

/// Returns a builder which can be awaited to obtain a reaction or stream of reactions sent in
/// this channel.
#[cfg(feature = "collector")]
pub fn await_reaction(self, shard_messenger: ShardMessenger) -> ReactionCollector {
ReactionCollector::new(shard_messenger).channel_id(self)
}

/// Same as [`Self::await_reaction`].
#[cfg(feature = "collector")]
pub fn await_reactions(self, shard_messenger: ShardMessenger) -> ReactionCollector {
self.await_reaction(shard_messenger)
}

/// Gets a stage instance.
///
/// # Errors
Expand Down
59 changes: 0 additions & 59 deletions src/model/channel/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,8 @@ use nonmax::NonMaxU64;
use crate::builder::{CreateAllowedMentions, CreateMessage, EditMessage};
#[cfg(all(feature = "cache", feature = "model"))]
use crate::cache::{Cache, GuildRef};
#[cfg(feature = "collector")]
use crate::collector::{
ComponentInteractionCollector,
ModalInteractionCollector,
ReactionCollector,
};
#[cfg(feature = "model")]
use crate::constants;
#[cfg(feature = "collector")]
use crate::gateway::ShardMessenger;
#[cfg(feature = "model")]
use crate::http::{CacheHttp, Http};
use crate::model::prelude::*;
Expand Down Expand Up @@ -941,57 +933,6 @@ impl MessageId {
format!("https://discord.com/channels/@me/{channel_id}/{self}")
}
}

/// Returns a builder which can be awaited to obtain a reaction or stream of reactions on this
/// message.
#[cfg(feature = "collector")]
pub fn await_reaction(self, shard_messenger: ShardMessenger) -> ReactionCollector {
ReactionCollector::new(shard_messenger).message_id(self)
}

/// Same as [`Self::await_reaction`].
#[cfg(feature = "collector")]
pub fn await_reactions(self, shard_messenger: ShardMessenger) -> ReactionCollector {
self.await_reaction(shard_messenger)
}

/// Returns a builder which can be awaited to obtain a single component interactions or a
/// stream of component interactions on this message.
#[cfg(feature = "collector")]
pub fn await_component_interaction(
self,
shard_messenger: ShardMessenger,
) -> ComponentInteractionCollector {
ComponentInteractionCollector::new(shard_messenger).message_id(self)
}

/// Same as [`Self::await_component_interaction`].
#[cfg(feature = "collector")]
pub fn await_component_interactions(
self,
shard_messenger: ShardMessenger,
) -> ComponentInteractionCollector {
self.await_component_interaction(shard_messenger)
}

/// Returns a builder which can be awaited to obtain a model submit interaction or stream of
/// modal submit interactions on this message.
#[cfg(feature = "collector")]
pub fn await_modal_interaction(
self,
shard_messenger: ShardMessenger,
) -> ModalInteractionCollector {
ModalInteractionCollector::new(shard_messenger).message_id(self)
}

/// Same as [`Self::await_modal_interaction`].
#[cfg(feature = "collector")]
pub fn await_modal_interactions(
self,
shard_messenger: ShardMessenger,
) -> ModalInteractionCollector {
self.await_modal_interaction(shard_messenger)
}
}

#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
Expand Down
29 changes: 0 additions & 29 deletions src/model/guild/guild_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ use crate::builder::{
};
#[cfg(all(feature = "cache", feature = "model"))]
use crate::cache::{Cache, GuildRef};
#[cfg(feature = "collector")]
use crate::collector::{MessageCollector, ReactionCollector};
#[cfg(feature = "collector")]
use crate::gateway::ShardMessenger;
#[cfg(feature = "model")]
use crate::http::{CacheHttp, Http, UserPagination};
#[cfg(feature = "model")]
Expand Down Expand Up @@ -1401,31 +1397,6 @@ impl GuildId {
pub async fn webhooks(self, http: &Http) -> Result<Vec<Webhook>> {
http.get_guild_webhooks(self).await
}
/// Returns a builder which can be awaited to obtain a message or stream of messages in this
/// guild.
#[cfg(feature = "collector")]
pub fn await_reply(self, shard_messenger: ShardMessenger) -> MessageCollector {
MessageCollector::new(shard_messenger).guild_id(self)
}

/// Same as [`Self::await_reply`].
#[cfg(feature = "collector")]
pub fn await_replies(self, shard_messenger: ShardMessenger) -> MessageCollector {
self.await_reply(shard_messenger)
}

/// Returns a builder which can be awaited to obtain a message or stream of reactions sent in
/// this guild.
#[cfg(feature = "collector")]
pub fn await_reaction(self, shard_messenger: ShardMessenger) -> ReactionCollector {
ReactionCollector::new(shard_messenger).guild_id(self)
}

/// Same as [`Self::await_reaction`].
#[cfg(feature = "collector")]
pub fn await_reactions(self, shard_messenger: ShardMessenger) -> ReactionCollector {
self.await_reaction(shard_messenger)
}

/// Create a guild specific application [`Command`].
///
Expand Down
30 changes: 0 additions & 30 deletions src/model/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ use serde::{Deserialize, Serialize};
use super::prelude::*;
#[cfg(feature = "model")]
use crate::builder::{CreateMessage, EditProfile};
#[cfg(feature = "collector")]
use crate::collector::{MessageCollector, ReactionCollector};
#[cfg(feature = "collector")]
use crate::gateway::ShardMessenger;
#[cfg(feature = "model")]
use crate::http::{CacheHttp, Http};
#[cfg(feature = "model")]
Expand Down Expand Up @@ -663,32 +659,6 @@ impl UserId {

Ok(user)
}

/// Returns a builder which can be awaited to obtain a message or stream of messages sent by
/// this user.
#[cfg(feature = "collector")]
pub fn await_reply(self, shard_messenger: ShardMessenger) -> MessageCollector {
MessageCollector::new(shard_messenger).author_id(self)
}

/// Same as [`Self::await_reply`].
#[cfg(feature = "collector")]
pub fn await_replies(self, shard_messenger: ShardMessenger) -> MessageCollector {
self.await_reply(shard_messenger)
}

/// Returns a builder which can be awaited to obtain a reaction or stream of reactions sent by
/// this user.
#[cfg(feature = "collector")]
pub fn await_reaction(self, shard_messenger: ShardMessenger) -> ReactionCollector {
ReactionCollector::new(shard_messenger).author_id(self)
}

/// Same as [`Self::await_reaction`].
#[cfg(feature = "collector")]
pub fn await_reactions(self, shard_messenger: ShardMessenger) -> ReactionCollector {
self.await_reaction(shard_messenger)
}
}

impl From<Member> for UserId {
Expand Down

0 comments on commit 9e3d21b

Please sign in to comment.