Skip to content

Commit f3749ac

Browse files
committed
refactor(slash_commands): refactored slash commands register system
1 parent 8d7cd21 commit f3749ac

18 files changed

Lines changed: 1751 additions & 1402 deletions

File tree

Lines changed: 94 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use crate::commands::add_staff::common::add_user_to_channel;
2+
use crate::commands::{BoxFuture, RegistrableCommand};
23
use crate::config::Config;
34
use crate::db::thread_exists;
45
use crate::errors::CommandError::InvalidFormat;
56
use crate::errors::ThreadError::NotAThreadChannel;
6-
use crate::errors::{CommandError, ModmailError, ModmailResult, common};
7+
use crate::errors::{common, CommandError, ModmailError, ModmailResult};
78
use crate::i18n::get_translated_message;
89
use crate::utils::command::defer_response::defer_response;
910
use crate::utils::message::message_builder::MessageBuilder;
@@ -13,84 +14,106 @@ use serenity::all::{
1314
};
1415
use std::collections::HashMap;
1516

16-
pub async fn register(config: &Config) -> CreateCommand {
17-
let cmd_desc = get_translated_message(
18-
config,
19-
"slash_command.add_staff_command_description",
20-
None,
21-
None,
22-
None,
23-
None,
24-
)
25-
.await;
26-
let user_id_desc = get_translated_message(
27-
config,
28-
"slash_command.add_staff_user_id_argument",
29-
None,
30-
None,
31-
None,
32-
None,
33-
)
34-
.await;
17+
pub struct AddStaffCommand;
3518

36-
CreateCommand::new("add_staff")
37-
.description(cmd_desc)
38-
.add_option(
39-
CreateCommandOption::new(CommandOptionType::User, "user_id", user_id_desc)
40-
.required(true),
41-
)
42-
}
19+
impl RegistrableCommand for AddStaffCommand {
20+
fn name(&self) -> &'static str {
21+
"add_staff"
22+
}
4323

44-
pub async fn run(
45-
ctx: &Context,
46-
command: &CommandInteraction,
47-
_options: &[ResolvedOption<'_>],
48-
config: &Config,
49-
) -> ModmailResult<()> {
50-
let pool = config
51-
.db_pool
52-
.as_ref()
53-
.ok_or_else(common::database_connection_failed)?;
24+
fn register(&self, config: &Config) -> BoxFuture<Vec<CreateCommand>> {
25+
let config = config.clone();
5426

55-
defer_response(&ctx, &command).await?;
27+
Box::pin(async move {
28+
let cmd_desc = get_translated_message(
29+
&config,
30+
"slash_command.add_staff_command_description",
31+
None,
32+
None,
33+
None,
34+
None,
35+
)
36+
.await;
5637

57-
let user_id = match command
58-
.data
59-
.options
60-
.iter()
61-
.find(|opt| opt.name == "user_id")
62-
{
63-
Some(opt) => match &opt.value {
64-
CommandDataOptionValue::User(user_id) => *user_id,
65-
_ => {
66-
return Err(ModmailError::Command(CommandError::InvalidArguments(
67-
"user_id".to_string(),
68-
)));
69-
}
70-
},
71-
None => return Err(ModmailError::Command(CommandError::MissingArguments)),
72-
};
38+
let user_id_desc = get_translated_message(
39+
&config,
40+
"slash_command.add_staff_user_id_argument",
41+
None,
42+
None,
43+
None,
44+
None,
45+
)
46+
.await;
47+
48+
vec![
49+
CreateCommand::new("add_staff")
50+
.description(cmd_desc)
51+
.add_option(
52+
CreateCommandOption::new(CommandOptionType::User, "user_id", user_id_desc)
53+
.required(true),
54+
),
55+
]
56+
})
57+
}
58+
59+
fn run(
60+
&self,
61+
ctx: &Context,
62+
command: &CommandInteraction,
63+
_options: &[ResolvedOption<'_>],
64+
config: &Config,
65+
) -> BoxFuture<ModmailResult<()>> {
66+
let ctx = ctx.clone();
67+
let command = command.clone();
68+
let config = config.clone();
69+
70+
Box::pin(async move {
71+
let pool = config
72+
.db_pool
73+
.as_ref()
74+
.ok_or_else(common::database_connection_failed)?;
75+
76+
defer_response(&ctx, &command).await?;
77+
78+
let user_id = match command
79+
.data
80+
.options
81+
.iter()
82+
.find(|opt| opt.name == "user_id")
83+
{
84+
Some(opt) => match &opt.value {
85+
CommandDataOptionValue::User(user_id) => *user_id,
86+
_ => {
87+
return Err(ModmailError::Command(CommandError::InvalidArguments(
88+
"user_id".to_string(),
89+
)));
90+
}
91+
},
92+
None => return Err(ModmailError::Command(CommandError::MissingArguments)),
93+
};
7394

74-
if thread_exists(command.user.id, pool).await {
75-
match add_user_to_channel(ctx, command.channel_id, user_id).await {
76-
Ok(_) => {
77-
let mut params = HashMap::new();
78-
params.insert("user".to_string(), format!("<@{}>", user_id));
95+
if thread_exists(command.user.id, pool).await {
96+
match add_user_to_channel(&ctx, command.channel_id, user_id).await {
97+
Ok(_) => {
98+
let mut params = HashMap::new();
99+
params.insert("user".to_string(), format!("<@{}>", user_id));
79100

80-
let response = MessageBuilder::system_message(ctx, config)
81-
.translated_content("add_staff.add_success", Some(&params), None, None)
82-
.await
83-
.to_channel(command.channel_id)
84-
.build_interaction_message_followup()
85-
.await;
101+
let response = MessageBuilder::system_message(&ctx, &config)
102+
.translated_content("add_staff.add_success", Some(&params), None, None)
103+
.await
104+
.to_channel(command.channel_id)
105+
.build_interaction_message_followup()
106+
.await;
86107

87-
let _ = command.create_followup(&ctx.http, response).await;
108+
let _ = command.create_followup(&ctx.http, response).await;
88109

89-
Ok(())
110+
Ok(())
111+
}
112+
Err(..) => Err(ModmailError::Command(InvalidFormat)),
113+
}
114+
} else {
115+
Err(ModmailError::Thread(NotAThreadChannel))
90116
}
91-
Err(..) => Err(ModmailError::Command(InvalidFormat)),
92-
}
93-
} else {
94-
Err(ModmailError::Thread(NotAThreadChannel))
117+
})
95118
}
96119
}

src/commands/alert/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::config::Config;
22
use crate::db::{cancel_alert_for_staff, get_user_id_from_channel_id, set_alert_for_staff};
33
use crate::errors::DatabaseError::QueryFailed;
44
use crate::errors::DiscordError::ApiError;
5-
use crate::errors::{ModmailError, ModmailResult, common};
5+
use crate::errors::{common, ModmailError, ModmailResult};
66
use crate::utils::message::message_builder::MessageBuilder;
77
use serenity::all::colours::branding::GREEN;
88
use serenity::all::{CommandInteraction, Context, CreateInteractionResponse, Message};

src/commands/alert/slash_command/alert.rs

Lines changed: 77 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,73 +2,96 @@ use crate::commands::alert::common::{
22
get_thread_user_id_from_command, handle_cancel_alert_from_command,
33
handle_set_alert_from_command,
44
};
5+
use crate::commands::{BoxFuture, RegistrableCommand};
56
use crate::config::Config;
6-
use crate::errors::{CommandError, ModmailError, ModmailResult, common};
7+
use crate::errors::{common, CommandError, ModmailError, ModmailResult};
78
use crate::i18n::get_translated_message;
89
use crate::utils::command::defer_response::defer_response;
910
use serenity::all::{
1011
CommandDataOptionValue, CommandInteraction, CommandOptionType, Context, CreateCommand,
1112
CreateCommandOption, ResolvedOption,
1213
};
1314

14-
pub async fn register(config: &Config) -> CreateCommand {
15-
let cmd_desc = get_translated_message(
16-
config,
17-
"slash_command.alert_command_description",
18-
None,
19-
None,
20-
None,
21-
None,
22-
)
23-
.await;
24-
let cancel_desc = get_translated_message(
25-
config,
26-
"slash_command.alert_cancel_argument",
27-
None,
28-
None,
29-
None,
30-
None,
31-
)
32-
.await;
15+
pub struct AlertCommand;
3316

34-
CreateCommand::new("alert")
35-
.description(cmd_desc)
36-
.add_option(
37-
CreateCommandOption::new(CommandOptionType::Boolean, "cancel", cancel_desc)
38-
.required(false),
39-
)
40-
}
17+
#[async_trait::async_trait]
18+
impl RegistrableCommand for AlertCommand {
19+
fn name(&self) -> &'static str {
20+
"alert"
21+
}
4122

42-
pub async fn run(
43-
ctx: &Context,
44-
command: &CommandInteraction,
45-
_options: &[ResolvedOption<'_>],
46-
config: &Config,
47-
) -> ModmailResult<()> {
48-
let pool = config
49-
.db_pool
50-
.as_ref()
51-
.ok_or_else(common::database_connection_failed)?;
23+
fn register(&self, config: &Config) -> BoxFuture<Vec<CreateCommand>> {
24+
let config = config.clone();
5225

53-
defer_response(&ctx, &command).await?;
26+
Box::pin(async move {
27+
let cmd_desc = get_translated_message(
28+
&config,
29+
"slash_command.alert_command_description",
30+
None,
31+
None,
32+
None,
33+
None,
34+
)
35+
.await;
36+
let cancel_desc = get_translated_message(
37+
&config,
38+
"slash_command.alert_cancel_argument",
39+
None,
40+
None,
41+
None,
42+
None,
43+
)
44+
.await;
5445

55-
let user_id = get_thread_user_id_from_command(ctx, command, config, pool).await?;
46+
vec![
47+
CreateCommand::new("alert")
48+
.description(cmd_desc)
49+
.add_option(
50+
CreateCommandOption::new(CommandOptionType::Boolean, "cancel", cancel_desc)
51+
.required(false),
52+
),
53+
]
54+
})
55+
}
5656

57-
let is_cancel = match command.data.options.iter().find(|opt| opt.name == "cancel") {
58-
Some(opt) => match &opt.value {
59-
CommandDataOptionValue::Boolean(cancel) => *cancel,
60-
_ => {
61-
return Err(ModmailError::Command(CommandError::InvalidArguments(
62-
"user_id".to_string(),
63-
)));
64-
}
65-
},
66-
None => false,
67-
};
57+
fn run(
58+
&self,
59+
ctx: &Context,
60+
command: &CommandInteraction,
61+
options: &[ResolvedOption<'_>],
62+
config: &Config,
63+
) -> BoxFuture<ModmailResult<()>> {
64+
let ctx = ctx.clone();
65+
let command = command.clone();
66+
let config = config.clone();
67+
68+
Box::pin(async move {
69+
let pool = config
70+
.db_pool
71+
.as_ref()
72+
.ok_or_else(common::database_connection_failed)?;
6873

69-
if is_cancel {
70-
handle_cancel_alert_from_command(ctx, command, config, user_id, pool).await
71-
} else {
72-
handle_set_alert_from_command(ctx, command, config, user_id, pool).await
74+
defer_response(&ctx, &command).await?;
75+
76+
let user_id = get_thread_user_id_from_command(&ctx, &command, &config, pool).await?;
77+
78+
let is_cancel = match command.data.options.iter().find(|opt| opt.name == "cancel") {
79+
Some(opt) => match &opt.value {
80+
CommandDataOptionValue::Boolean(cancel) => *cancel,
81+
_ => {
82+
return Err(ModmailError::Command(CommandError::InvalidArguments(
83+
"user_id".to_string(),
84+
)));
85+
}
86+
},
87+
None => false,
88+
};
89+
90+
if is_cancel {
91+
handle_cancel_alert_from_command(&ctx, &command, &config, user_id, pool).await
92+
} else {
93+
handle_set_alert_from_command(&ctx, &command, &config, user_id, pool).await
94+
}
95+
})
7396
}
7497
}

0 commit comments

Comments
 (0)