typing
This commit is contained in:
parent
bae0433bd9
commit
395a8481f1
@ -27,4 +27,4 @@ sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "macros", "mysql",
|
|||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
|
|
||||||
[dependencies.regex_command_attr]
|
[dependencies.regex_command_attr]
|
||||||
path = "./regex_command_attr"
|
path = "command_attributes"
|
||||||
|
@ -9,9 +9,7 @@ use serenity::{
|
|||||||
client::Context,
|
client::Context,
|
||||||
model::{
|
model::{
|
||||||
channel::Message,
|
channel::Message,
|
||||||
guild::ActionRole::Create,
|
|
||||||
id::{ChannelId, MessageId, RoleId},
|
id::{ChannelId, MessageId, RoleId},
|
||||||
interactions::message_component::ButtonStyle,
|
|
||||||
misc::Mentionable,
|
misc::Mentionable,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -19,7 +17,9 @@ use serenity::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
component_models::{ComponentDataModel, Restrict},
|
component_models::{ComponentDataModel, Restrict},
|
||||||
consts::{REGEX_ALIAS, REGEX_COMMANDS, THEME_COLOR},
|
consts::{REGEX_ALIAS, REGEX_COMMANDS, THEME_COLOR},
|
||||||
framework::{CommandInvoke, CreateGenericResponse, PermissionLevel},
|
framework::{
|
||||||
|
CommandInvoke, CommandOptions, CreateGenericResponse, OptionValue, PermissionLevel,
|
||||||
|
},
|
||||||
models::{channel_data::ChannelData, guild_data::GuildData, user_data::UserData, CtxData},
|
models::{channel_data::ChannelData, guild_data::GuildData, user_data::UserData, CtxData},
|
||||||
PopularTimezones, RegexFramework, SQLPool,
|
PopularTimezones, RegexFramework, SQLPool,
|
||||||
};
|
};
|
||||||
@ -38,14 +38,14 @@ use crate::{
|
|||||||
async fn blacklist(
|
async fn blacklist(
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
invoke: &(dyn CommandInvoke + Send + Sync),
|
invoke: &(dyn CommandInvoke + Send + Sync),
|
||||||
args: HashMap<String, String>,
|
args: CommandOptions,
|
||||||
) {
|
) {
|
||||||
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
||||||
|
|
||||||
let channel = match args.get("channel") {
|
let channel = match args.get("channel") {
|
||||||
Some(channel_id) => ChannelId(channel_id.parse::<u64>().unwrap()),
|
Some(OptionValue::Channel(channel_id)) => *channel_id,
|
||||||
|
|
||||||
None => invoke.channel_id(),
|
_ => invoke.channel_id(),
|
||||||
}
|
}
|
||||||
.to_channel_cached(&ctx)
|
.to_channel_cached(&ctx)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -82,17 +82,13 @@ async fn blacklist(
|
|||||||
kind = "String",
|
kind = "String",
|
||||||
required = false
|
required = false
|
||||||
)]
|
)]
|
||||||
async fn timezone(
|
async fn timezone(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync), args: CommandOptions) {
|
||||||
ctx: &Context,
|
|
||||||
invoke: &(dyn CommandInvoke + Send + Sync),
|
|
||||||
args: HashMap<String, String>,
|
|
||||||
) {
|
|
||||||
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
||||||
let mut user_data = ctx.user_data(invoke.author_id()).await.unwrap();
|
let mut user_data = ctx.user_data(invoke.author_id()).await.unwrap();
|
||||||
|
|
||||||
let footer_text = format!("Current timezone: {}", user_data.timezone);
|
let footer_text = format!("Current timezone: {}", user_data.timezone);
|
||||||
|
|
||||||
if let Some(timezone) = args.get("timezone") {
|
if let Some(OptionValue::String(timezone)) = args.get("timezone") {
|
||||||
match timezone.parse::<Tz>() {
|
match timezone.parse::<Tz>() {
|
||||||
Ok(tz) => {
|
Ok(tz) => {
|
||||||
user_data.timezone = timezone.clone();
|
user_data.timezone = timezone.clone();
|
||||||
@ -237,65 +233,66 @@ async fn prefix(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync), args:
|
|||||||
)]
|
)]
|
||||||
#[supports_dm(false)]
|
#[supports_dm(false)]
|
||||||
#[required_permissions(Restricted)]
|
#[required_permissions(Restricted)]
|
||||||
async fn restrict(
|
async fn restrict(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync), args: CommandOptions) {
|
||||||
ctx: &Context,
|
|
||||||
invoke: &(dyn CommandInvoke + Send + Sync),
|
|
||||||
args: HashMap<String, String>,
|
|
||||||
) {
|
|
||||||
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
||||||
let framework = ctx.data.read().await.get::<RegexFramework>().cloned().unwrap();
|
let framework = ctx.data.read().await.get::<RegexFramework>().cloned().unwrap();
|
||||||
|
|
||||||
let role = RoleId(args.get("role").unwrap().parse::<u64>().unwrap());
|
if let Some(OptionValue::Role(role)) = args.get("role") {
|
||||||
|
let restricted_commands =
|
||||||
|
sqlx::query!("SELECT command FROM command_restrictions WHERE role_id = ?", role.0)
|
||||||
|
.fetch_all(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.map(|row| row.command.clone())
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
let restricted_commands =
|
let restrictable_commands = framework
|
||||||
sqlx::query!("SELECT command FROM command_restrictions WHERE role_id = ?", role.0)
|
.commands
|
||||||
.fetch_all(&pool)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|row| row.command.clone())
|
.filter(|c| c.required_permissions == PermissionLevel::Managed)
|
||||||
|
.map(|c| c.names[0].to_string())
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
let restrictable_commands = framework
|
let len = restrictable_commands.len();
|
||||||
.commands
|
|
||||||
.iter()
|
|
||||||
.filter(|c| c.required_permissions == PermissionLevel::Managed)
|
|
||||||
.map(|c| c.names[0].to_string())
|
|
||||||
.collect::<Vec<String>>();
|
|
||||||
|
|
||||||
let len = restrictable_commands.len();
|
let restrict_pl = ComponentDataModel::Restrict(Restrict { role_id: *role });
|
||||||
|
|
||||||
let restrict_pl = ComponentDataModel::Restrict(Restrict { role_id: role });
|
invoke
|
||||||
|
.respond(
|
||||||
|
ctx.http.clone(),
|
||||||
|
CreateGenericResponse::new()
|
||||||
|
.content(format!(
|
||||||
|
"Select the commands to allow to {} from below:",
|
||||||
|
role.mention()
|
||||||
|
))
|
||||||
|
.components(|c| {
|
||||||
|
c.create_action_row(|row| {
|
||||||
|
row.create_select_menu(|select| {
|
||||||
|
select
|
||||||
|
.custom_id(restrict_pl.to_custom_id())
|
||||||
|
.options(|options| {
|
||||||
|
for command in restrictable_commands {
|
||||||
|
options.create_option(|opt| {
|
||||||
|
opt.label(&command)
|
||||||
|
.value(&command)
|
||||||
|
.default_selection(
|
||||||
|
restricted_commands.contains(&command),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
invoke
|
options
|
||||||
.respond(
|
})
|
||||||
ctx.http.clone(),
|
.min_values(0)
|
||||||
CreateGenericResponse::new()
|
.max_values(len as u64)
|
||||||
.content(format!("Select the commands to allow to {} from below:", role.mention()))
|
})
|
||||||
.components(|c| {
|
|
||||||
c.create_action_row(|row| {
|
|
||||||
row.create_select_menu(|select| {
|
|
||||||
select
|
|
||||||
.custom_id(restrict_pl.to_custom_id())
|
|
||||||
.options(|options| {
|
|
||||||
for command in restrictable_commands {
|
|
||||||
options.create_option(|opt| {
|
|
||||||
opt.label(&command).value(&command).default_selection(
|
|
||||||
restricted_commands.contains(&command),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
options
|
|
||||||
})
|
|
||||||
.min_values(0)
|
|
||||||
.max_values(len as u64)
|
|
||||||
})
|
})
|
||||||
})
|
}),
|
||||||
}),
|
)
|
||||||
)
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -24,7 +24,7 @@ use crate::{
|
|||||||
EMBED_DESCRIPTION_MAX_LENGTH, REGEX_CHANNEL_USER, REGEX_NATURAL_COMMAND_1,
|
EMBED_DESCRIPTION_MAX_LENGTH, REGEX_CHANNEL_USER, REGEX_NATURAL_COMMAND_1,
|
||||||
REGEX_NATURAL_COMMAND_2, REGEX_REMIND_COMMAND, THEME_COLOR,
|
REGEX_NATURAL_COMMAND_2, REGEX_REMIND_COMMAND, THEME_COLOR,
|
||||||
},
|
},
|
||||||
framework::{CommandInvoke, CreateGenericResponse},
|
framework::{CommandInvoke, CommandOptions, CreateGenericResponse, OptionValue},
|
||||||
models::{
|
models::{
|
||||||
channel_data::ChannelData,
|
channel_data::ChannelData,
|
||||||
guild_data::GuildData,
|
guild_data::GuildData,
|
||||||
@ -52,11 +52,7 @@ use crate::{
|
|||||||
)]
|
)]
|
||||||
#[supports_dm(false)]
|
#[supports_dm(false)]
|
||||||
#[required_permissions(Restricted)]
|
#[required_permissions(Restricted)]
|
||||||
async fn pause(
|
async fn pause(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync), args: CommandOptions) {
|
||||||
ctx: &Context,
|
|
||||||
invoke: &(dyn CommandInvoke + Send + Sync),
|
|
||||||
args: HashMap<String, String>,
|
|
||||||
) {
|
|
||||||
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
||||||
|
|
||||||
let timezone = UserData::timezone_of(&invoke.author_id(), &pool).await;
|
let timezone = UserData::timezone_of(&invoke.author_id(), &pool).await;
|
||||||
@ -64,7 +60,7 @@ async fn pause(
|
|||||||
let mut channel = ctx.channel_data(invoke.channel_id()).await.unwrap();
|
let mut channel = ctx.channel_data(invoke.channel_id()).await.unwrap();
|
||||||
|
|
||||||
match args.get("until") {
|
match args.get("until") {
|
||||||
Some(until) => {
|
Some(OptionValue::String(until)) => {
|
||||||
let parsed = natural_parser(until, &timezone.to_string()).await;
|
let parsed = natural_parser(until, &timezone.to_string()).await;
|
||||||
|
|
||||||
if let Some(timestamp) = parsed {
|
if let Some(timestamp) = parsed {
|
||||||
@ -94,7 +90,7 @@ async fn pause(
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
_ => {
|
||||||
channel.paused = !channel.paused;
|
channel.paused = !channel.paused;
|
||||||
channel.paused_until = None;
|
channel.paused_until = None;
|
||||||
|
|
||||||
@ -142,16 +138,12 @@ async fn pause(
|
|||||||
required = false
|
required = false
|
||||||
)]
|
)]
|
||||||
#[required_permissions(Restricted)]
|
#[required_permissions(Restricted)]
|
||||||
async fn offset(
|
async fn offset(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync), args: CommandOptions) {
|
||||||
ctx: &Context,
|
|
||||||
invoke: &(dyn CommandInvoke + Send + Sync),
|
|
||||||
args: HashMap<String, String>,
|
|
||||||
) {
|
|
||||||
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
||||||
|
|
||||||
let combined_time = args.get("hours").map_or(0, |h| h.parse::<i64>().unwrap() * 3600)
|
let combined_time = args.get("hours").map_or(0, |h| h.as_i64().unwrap() * 3600)
|
||||||
+ args.get("minutes").map_or(0, |m| m.parse::<i64>().unwrap() * 60)
|
+ args.get("minutes").map_or(0, |m| m.as_i64().unwrap() * 60)
|
||||||
+ args.get("seconds").map_or(0, |s| s.parse::<i64>().unwrap());
|
+ args.get("seconds").map_or(0, |s| s.as_i64().unwrap());
|
||||||
|
|
||||||
if combined_time == 0 {
|
if combined_time == 0 {
|
||||||
let _ = invoke
|
let _ = invoke
|
||||||
@ -223,15 +215,11 @@ WHERE FIND_IN_SET(channels.`channel`, ?)",
|
|||||||
required = false
|
required = false
|
||||||
)]
|
)]
|
||||||
#[required_permissions(Restricted)]
|
#[required_permissions(Restricted)]
|
||||||
async fn nudge(
|
async fn nudge(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync), args: CommandOptions) {
|
||||||
ctx: &Context,
|
|
||||||
invoke: &(dyn CommandInvoke + Send + Sync),
|
|
||||||
args: HashMap<String, String>,
|
|
||||||
) {
|
|
||||||
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
||||||
|
|
||||||
let combined_time = args.get("minutes").map_or(0, |m| m.parse::<i64>().unwrap() * 60)
|
let combined_time = args.get("minutes").map_or(0, |m| m.as_i64().unwrap() * 60)
|
||||||
+ args.get("seconds").map_or(0, |s| s.parse::<i64>().unwrap());
|
+ args.get("seconds").map_or(0, |s| s.as_i64().unwrap());
|
||||||
|
|
||||||
if combined_time < i16::MIN as i64 || combined_time > i16::MAX as i64 {
|
if combined_time < i16::MIN as i64 || combined_time > i16::MAX as i64 {
|
||||||
let _ = invoke
|
let _ = invoke
|
||||||
@ -279,20 +267,16 @@ async fn nudge(
|
|||||||
required = false
|
required = false
|
||||||
)]
|
)]
|
||||||
#[required_permissions(Managed)]
|
#[required_permissions(Managed)]
|
||||||
async fn look(
|
async fn look(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync), args: CommandOptions) {
|
||||||
ctx: &Context,
|
|
||||||
invoke: &(dyn CommandInvoke + Send + Sync),
|
|
||||||
args: HashMap<String, String>,
|
|
||||||
) {
|
|
||||||
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
||||||
|
|
||||||
let timezone = UserData::timezone_of(&invoke.author_id(), &pool).await;
|
let timezone = UserData::timezone_of(&invoke.author_id(), &pool).await;
|
||||||
|
|
||||||
let flags = LookFlags {
|
let flags = LookFlags {
|
||||||
show_disabled: args.get("disabled").map(|b| b == "true").unwrap_or(true),
|
show_disabled: args.get("disabled").map(|i| i.as_bool()).flatten().unwrap_or(true),
|
||||||
channel_id: args.get("channel").map(|c| ChannelId(c.parse::<u64>().unwrap())),
|
channel_id: args.get("channel").map(|i| i.as_channel_id()).flatten(),
|
||||||
time_display: args.get("relative").map_or(TimeDisplayType::Relative, |b| {
|
time_display: args.get("relative").map_or(TimeDisplayType::Relative, |b| {
|
||||||
if b == "true" {
|
if b.as_bool() == Some(true) {
|
||||||
TimeDisplayType::Relative
|
TimeDisplayType::Relative
|
||||||
} else {
|
} else {
|
||||||
TimeDisplayType::Absolute
|
TimeDisplayType::Absolute
|
||||||
@ -473,11 +457,7 @@ INSERT INTO events (event_name, bulk_count, guild_id, user_id) VALUES ('delete',
|
|||||||
#[description("Delete a timer")]
|
#[description("Delete a timer")]
|
||||||
#[arg(name = "name", description = "Name of the timer to delete", kind = "String", required = true)]
|
#[arg(name = "name", description = "Name of the timer to delete", kind = "String", required = true)]
|
||||||
#[required_permissions(Managed)]
|
#[required_permissions(Managed)]
|
||||||
async fn timer(
|
async fn timer(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync), args: CommandOptions) {
|
||||||
ctx: &Context,
|
|
||||||
invoke: &(dyn CommandInvoke + Send + Sync),
|
|
||||||
args: HashMap<String, String>,
|
|
||||||
) {
|
|
||||||
fn time_difference(start_time: NaiveDateTime) -> String {
|
fn time_difference(start_time: NaiveDateTime) -> String {
|
||||||
let unix_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i64;
|
let unix_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i64;
|
||||||
let now = NaiveDateTime::from_timestamp(unix_time, 0);
|
let now = NaiveDateTime::from_timestamp(unix_time, 0);
|
||||||
@ -495,8 +475,8 @@ async fn timer(
|
|||||||
|
|
||||||
let owner = invoke.guild_id().map(|g| g.0).unwrap_or_else(|| invoke.author_id().0);
|
let owner = invoke.guild_id().map(|g| g.0).unwrap_or_else(|| invoke.author_id().0);
|
||||||
|
|
||||||
match args.get("").map(|s| s.as_str()) {
|
match args.subcommand.clone().unwrap().as_str() {
|
||||||
Some("start") => {
|
"start" => {
|
||||||
let count = Timer::count_from_owner(owner, &pool).await;
|
let count = Timer::count_from_owner(owner, &pool).await;
|
||||||
|
|
||||||
if count >= 25 {
|
if count >= 25 {
|
||||||
@ -508,7 +488,7 @@ async fn timer(
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
} else {
|
} else {
|
||||||
let name = args.get("name").unwrap();
|
let name = args.get("name").unwrap().to_string();
|
||||||
|
|
||||||
if name.len() <= 32 {
|
if name.len() <= 32 {
|
||||||
Timer::create(&name, owner, &pool).await;
|
Timer::create(&name, owner, &pool).await;
|
||||||
@ -530,8 +510,8 @@ async fn timer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some("delete") => {
|
"delete" => {
|
||||||
let name = args.get("name").unwrap();
|
let name = args.get("name").unwrap().to_string();
|
||||||
|
|
||||||
let exists = sqlx::query!(
|
let exists = sqlx::query!(
|
||||||
"
|
"
|
||||||
@ -570,7 +550,7 @@ DELETE FROM timers WHERE owner = ? AND name = ?
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some("list") => {
|
"list" => {
|
||||||
let timers = Timer::from_owner(owner, &pool).await;
|
let timers = Timer::from_owner(owner, &pool).await;
|
||||||
|
|
||||||
if timers.len() > 0 {
|
if timers.len() > 0 {
|
||||||
|
193
src/framework.rs
193
src/framework.rs
@ -18,13 +18,15 @@ use serenity::{
|
|||||||
model::{
|
model::{
|
||||||
channel::{Channel, GuildChannel, Message},
|
channel::{Channel, GuildChannel, Message},
|
||||||
guild::{Guild, Member},
|
guild::{Guild, Member},
|
||||||
id::{ChannelId, GuildId, MessageId, UserId},
|
id::{ChannelId, GuildId, MessageId, RoleId, UserId},
|
||||||
interactions::{
|
interactions::{
|
||||||
application_command::{
|
application_command::{
|
||||||
ApplicationCommand, ApplicationCommandInteraction, ApplicationCommandOptionType,
|
ApplicationCommand, ApplicationCommandInteraction, ApplicationCommandOption,
|
||||||
|
ApplicationCommandOptionType,
|
||||||
},
|
},
|
||||||
InteractionResponseType,
|
InteractionResponseType,
|
||||||
},
|
},
|
||||||
|
prelude::application_command::ApplicationCommandInteractionDataOption,
|
||||||
},
|
},
|
||||||
prelude::TypeMapKey,
|
prelude::TypeMapKey,
|
||||||
FutureExt, Result as SerenityResult,
|
FutureExt, Result as SerenityResult,
|
||||||
@ -281,10 +283,166 @@ pub struct Arg {
|
|||||||
pub options: &'static [&'static Self],
|
pub options: &'static [&'static Self],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum OptionValue {
|
||||||
|
String(String),
|
||||||
|
Integer(i64),
|
||||||
|
Boolean(bool),
|
||||||
|
User(UserId),
|
||||||
|
Channel(ChannelId),
|
||||||
|
Role(RoleId),
|
||||||
|
Mentionable(u64),
|
||||||
|
Number(f64),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OptionValue {
|
||||||
|
pub fn as_i64(&self) -> Option<i64> {
|
||||||
|
match self {
|
||||||
|
OptionValue::Integer(i) => Some(*i),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_bool(&self) -> Option<bool> {
|
||||||
|
match self {
|
||||||
|
OptionValue::Boolean(b) => Some(*b),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_channel_id(&self) -> Option<ChannelId> {
|
||||||
|
match self {
|
||||||
|
OptionValue::Channel(c) => Some(*c),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_string(&self) -> String {
|
||||||
|
match self {
|
||||||
|
OptionValue::String(s) => s.to_string(),
|
||||||
|
OptionValue::Integer(i) => i.to_string(),
|
||||||
|
OptionValue::Boolean(b) => b.to_string(),
|
||||||
|
OptionValue::User(u) => u.to_string(),
|
||||||
|
OptionValue::Channel(c) => c.to_string(),
|
||||||
|
OptionValue::Role(r) => r.to_string(),
|
||||||
|
OptionValue::Mentionable(m) => m.to_string(),
|
||||||
|
OptionValue::Number(n) => n.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CommandOptions {
|
||||||
|
pub command: String,
|
||||||
|
pub subcommand: Option<String>,
|
||||||
|
pub subcommand_group: Option<String>,
|
||||||
|
pub options: HashMap<String, OptionValue>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommandOptions {
|
||||||
|
pub fn get(&self, key: &str) -> Option<&OptionValue> {
|
||||||
|
self.options.get(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ApplicationCommandInteraction> for CommandOptions {
|
||||||
|
fn from(interaction: ApplicationCommandInteraction) -> Self {
|
||||||
|
fn match_option(
|
||||||
|
option: ApplicationCommandInteractionDataOption,
|
||||||
|
cmd_opts: &mut CommandOptions,
|
||||||
|
) {
|
||||||
|
match option.kind {
|
||||||
|
ApplicationCommandOptionType::SubCommand => {
|
||||||
|
cmd_opts.subcommand = Some(option.name);
|
||||||
|
|
||||||
|
for opt in option.options {
|
||||||
|
match_option(opt, cmd_opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ApplicationCommandOptionType::SubCommandGroup => {
|
||||||
|
cmd_opts.subcommand_group = Some(option.name);
|
||||||
|
|
||||||
|
for opt in option.options {
|
||||||
|
match_option(opt, cmd_opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ApplicationCommandOptionType::String => {
|
||||||
|
cmd_opts.options.insert(
|
||||||
|
option.name,
|
||||||
|
OptionValue::String(option.value.unwrap().to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ApplicationCommandOptionType::Integer => {
|
||||||
|
cmd_opts.options.insert(
|
||||||
|
option.name,
|
||||||
|
OptionValue::Integer(option.value.map(|m| m.as_i64()).flatten().unwrap()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ApplicationCommandOptionType::Boolean => {
|
||||||
|
cmd_opts.options.insert(
|
||||||
|
option.name,
|
||||||
|
OptionValue::Boolean(option.value.map(|m| m.as_bool()).flatten().unwrap()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ApplicationCommandOptionType::User => {
|
||||||
|
cmd_opts.options.insert(
|
||||||
|
option.name,
|
||||||
|
OptionValue::User(UserId(
|
||||||
|
option.value.map(|m| m.as_u64()).flatten().unwrap(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ApplicationCommandOptionType::Channel => {
|
||||||
|
cmd_opts.options.insert(
|
||||||
|
option.name,
|
||||||
|
OptionValue::Channel(ChannelId(
|
||||||
|
option.value.map(|m| m.as_u64()).flatten().unwrap(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ApplicationCommandOptionType::Role => {
|
||||||
|
cmd_opts.options.insert(
|
||||||
|
option.name,
|
||||||
|
OptionValue::Role(RoleId(
|
||||||
|
option.value.map(|m| m.as_u64()).flatten().unwrap(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ApplicationCommandOptionType::Mentionable => {
|
||||||
|
cmd_opts.options.insert(
|
||||||
|
option.name,
|
||||||
|
OptionValue::Mentionable(
|
||||||
|
option.value.map(|m| m.as_u64()).flatten().unwrap(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ApplicationCommandOptionType::Number => {
|
||||||
|
cmd_opts.options.insert(
|
||||||
|
option.name,
|
||||||
|
OptionValue::Number(option.value.map(|m| m.as_f64()).flatten().unwrap()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cmd_opts = Self {
|
||||||
|
command: interaction.data.name,
|
||||||
|
subcommand: None,
|
||||||
|
subcommand_group: None,
|
||||||
|
options: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
for option in interaction.data.options {
|
||||||
|
match_option(option, &mut cmd_opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_opts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type SlashCommandFn = for<'fut> fn(
|
type SlashCommandFn = for<'fut> fn(
|
||||||
&'fut Context,
|
&'fut Context,
|
||||||
&'fut (dyn CommandInvoke + Sync + Send),
|
&'fut (dyn CommandInvoke + Sync + Send),
|
||||||
HashMap<String, String>,
|
CommandOptions,
|
||||||
) -> BoxFuture<'fut, ()>;
|
) -> BoxFuture<'fut, ()>;
|
||||||
|
|
||||||
type TextCommandFn = for<'fut> fn(
|
type TextCommandFn = for<'fut> fn(
|
||||||
@ -631,34 +789,7 @@ impl RegexFramework {
|
|||||||
let member = interaction.clone().member.unwrap();
|
let member = interaction.clone().member.unwrap();
|
||||||
|
|
||||||
if command.check_permissions(&ctx, &guild, &member).await {
|
if command.check_permissions(&ctx, &guild, &member).await {
|
||||||
let mut args = HashMap::new();
|
let args = CommandOptions::from(interaction.clone());
|
||||||
|
|
||||||
for arg in interaction.data.options.iter() {
|
|
||||||
if let Some(value) = &arg.value {
|
|
||||||
args.insert(
|
|
||||||
arg.name.clone(),
|
|
||||||
match value {
|
|
||||||
Value::Bool(b) => b.to_string(),
|
|
||||||
Value::Number(n) => n.to_string(),
|
|
||||||
Value::String(s) => s.to_owned(),
|
|
||||||
_ => String::new(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
args.insert("".to_string(), arg.name.clone());
|
|
||||||
for sub_arg in arg.options.iter().filter(|o| o.value.is_some()) {
|
|
||||||
args.insert(
|
|
||||||
sub_arg.name.clone(),
|
|
||||||
match sub_arg.value.as_ref().unwrap() {
|
|
||||||
Value::Bool(b) => b.to_string(),
|
|
||||||
Value::Number(n) => n.to_string(),
|
|
||||||
Value::String(s) => s.to_owned(),
|
|
||||||
_ => String::new(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ctx.check_executing(interaction.author_id()).await {
|
if !ctx.check_executing(interaction.author_id()).await {
|
||||||
ctx.set_executing(interaction.author_id()).await;
|
ctx.set_executing(interaction.author_id()).await;
|
||||||
|
Loading…
Reference in New Issue
Block a user