reminder-bot/src/utils.rs

164 lines
4.6 KiB
Rust

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<UserId>) -> 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<GuildId>,
) -> 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<String>) => {
$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<bool>) => {
$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<PartialChannel>) => {
$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<i64>) => {
$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;