1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use dashmap::DashMap;
use futures::future::BoxFuture;
use serenity::builder::CreateApplicationCommand;
use serenity::client::Context;
use serenity::model::guild::Guild;
use serenity::model::interactions::application_command::ApplicationCommand;
use serenity::model::interactions::application_command::ApplicationCommandInteraction;
mod whois;
type InteractionResult<'a> = BoxFuture<'a, serenity::Result<()>>;
pub type InteractionHandler =
for<'a> fn(&'a Context, &'a ApplicationCommandInteraction) -> InteractionResult<'a>;
type CommandBuilder = fn(&mut CreateApplicationCommand) -> &mut CreateApplicationCommand;
struct Command {
name: &'static str,
builder: CommandBuilder,
handler: InteractionHandler,
}
const COMMANDS: &'static [Command] = &[
Command {
name: whois::COMMAND_NAME,
builder: whois::create_whois,
handler: whois::handle_whois,
},
];
lazy_static! { static ref COMMAND_MAP: DashMap<String, InteractionHandler> = {
let map = DashMap::new();
for cmd in COMMANDS {
map.insert(cmd.name.to_string(), cmd.handler);
}
map
}; }
fn global_command_map() -> &'static DashMap<String, InteractionHandler> {
&COMMAND_MAP
}
pub fn get_handler(command_name: &str) -> Option<InteractionHandler> {
global_command_map()
.get(command_name)
.as_ref()
.map(|entry| *entry.value())
}
pub async fn register_commands_for_guild(ctx: &mut Context, guild: &Guild) -> serenity::Result<()> {
for cmd in COMMANDS {
let mut command_builder: CreateApplicationCommand = CreateApplicationCommand::default();
(cmd.builder)(&mut command_builder);
let json_map = serenity::utils::hashmap_to_json_map(command_builder.0);
let json_value = serde_json::Value::Object(json_map);
let created: ApplicationCommand = ctx
.http
.create_guild_application_command(*guild.id.as_u64(), &json_value)
.await?;
info!(
"Registered '/{}' command for '{}' guild (command ID: {}) (guild ID: {})",
created.name, guild.name, created.id, guild.id
);
}
return Ok(());
}