use poise::{ serenity_prelude::{ http::CacheHttp, model::id::{GuildId, UserId}, CreateEmbedFooter, CreateInteractionResponseMessage, }, CreateReply, }; use crate::{ consts::{CNC_GUILD, SUBSCRIPTION_ROLES}, ApplicationContext, Context, Error, }; pub async fn check_subscription(cache_http: impl CacheHttp, user_id: impl Into) -> bool { if let Some(subscription_guild) = *CNC_GUILD { let guild_member = GuildId::new(subscription_guild).member(cache_http, user_id).await; if let Ok(member) = guild_member { for role in member.roles { if SUBSCRIPTION_ROLES.contains(&role.get()) { return true; } } } false } else { true } } pub async fn check_guild_subscription( cache_http: impl CacheHttp, guild_id: impl Into, ) -> bool { if let Some(owner) = cache_http.cache().unwrap().guild(guild_id).map(|g| g.owner_id) { check_subscription(&cache_http, owner).await } else { false } } pub fn reply_to_interaction_response_message( reply: CreateReply, ) -> CreateInteractionResponseMessage { let mut builder = CreateInteractionResponseMessage::new().embeds(reply.embeds); if let Some(components) = reply.components { builder = builder.components(components) } builder } pub fn footer(ctx: Context<'_>) -> CreateEmbedFooter { let shard_count = ctx.serenity_context().cache.shard_count(); let shard = ctx.serenity_context().shard_id; CreateEmbedFooter::new(format!( "{}\nshard {} of {}", concat!(env!("CARGO_PKG_NAME"), " ver ", env!("CARGO_PKG_VERSION")), shard, shard_count, )) } pub trait Recordable { async fn run(self, ctx: Context<'_>) -> Result<(), Error>; } pub use recordable_derive::Recordable; pub trait Extract { fn extract(ctx: ApplicationContext) -> Self; } pub use extract_derive::Extract; macro_rules! extract_arg { ($ctx:ident, $name:ident, String) => { $ctx.args .iter() .find(|opt| opt.name == stringify!($name)) .map(|opt| &opt.value) .map_or_else( || String::new(), |v| match v { poise::serenity_prelude::ResolvedValue::String(s) => s.to_string(), _ => String::new(), }, ) }; ($ctx:ident, $name:ident, Option) => { $ctx.args .iter() .find(|opt| opt.name == stringify!($name)) .map(|opt| &opt.value) .map(|v| match v { poise::serenity_prelude::ResolvedValue::String(s) => Some(s.to_string()), _ => None, }) .flatten() }; ($ctx:ident, $name:ident, bool) => { $ctx.args.iter().find(|opt| opt.name == stringify!($name)).map(|opt| &opt.value).map_or( false, |v| match v { poise::serenity_prelude::ResolvedValue::Boolean(b) => b.to_owned(), _ => false, }, ) }; ($ctx:ident, $name:ident, Option) => { $ctx.args .iter() .find(|opt| opt.name == stringify!($name)) .map(|opt| &opt.value) .map(|v| match v { poise::serenity_prelude::ResolvedValue::Boolean(b) => Some(b.to_owned()), _ => None, }) .flatten() }; ($ctx:ident, $name:ident, Option) => { $ctx.args .iter() .find(|opt| opt.name == stringify!($name)) .map(|opt| &opt.value) .map(|v| match v { poise::serenity_prelude::ResolvedValue::Channel(partial) => { Some(partial.to_owned()) } _ => None, }) .flatten() .cloned() }; ($ctx:ident, $name:ident, i64) => { $ctx.args .iter() .find(|opt| opt.name == stringify!($name)) .map(|opt| &opt.value) .map(|v| match v { poise::serenity_prelude::ResolvedValue::Integer(int) => *int, _ => 0, }) .flatten() }; ($ctx:ident, $name:ident, Option) => { $ctx.args .iter() .find(|opt| opt.name == stringify!($name)) .map(|opt| &opt.value) .map(|v| match v { poise::serenity_prelude::ResolvedValue::Integer(int) => Some(*int), _ => None, }) .flatten() }; } pub(crate) use extract_arg;