Prepare architecture for custom Runtime
This commit is contained in:
parent
b34da70c8b
commit
de1eb03b13
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use serenity::{prelude::GatewayIntents, Client as SerenityClient};
|
use serenity::{prelude::GatewayIntents, Client as SerenityClient};
|
||||||
|
|
||||||
use crate::{database::Client as DatabaseClient, environment::get_env_variable};
|
use crate::{database::Client as DatabaseClient, environment::get_env_variable};
|
||||||
|
@ -6,18 +8,19 @@ use crate::discord::event_handler::Handler;
|
||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
serenity_client: SerenityClient,
|
serenity_client: SerenityClient,
|
||||||
|
database_client: Arc<Mutex<DatabaseClient>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
pub async fn new() -> Self {
|
pub async fn new() -> Self {
|
||||||
let mut database_client = DatabaseClient::new();
|
let database_client = Arc::new(Mutex::new(DatabaseClient::new()));
|
||||||
database_client.connect().await;
|
database_client.clone().lock().unwrap().connect();
|
||||||
|
|
||||||
let discord_token = get_env_variable("DISCORD_TOKEN");
|
let discord_token = get_env_variable("DISCORD_TOKEN");
|
||||||
let intents = GatewayIntents::GUILD_MESSAGES | GatewayIntents::MESSAGE_CONTENT;
|
let intents = GatewayIntents::GUILD_MESSAGES | GatewayIntents::MESSAGE_CONTENT;
|
||||||
|
|
||||||
let event_handler = Handler {
|
let event_handler = Handler {
|
||||||
database: database_client,
|
database: database_client.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let serenity_client = match SerenityClient::builder(discord_token, intents)
|
let serenity_client = match SerenityClient::builder(discord_token, intents)
|
||||||
|
@ -28,7 +31,10 @@ impl Client {
|
||||||
Err(e) => panic!("Failed to instantiate Discord Client: {e}"),
|
Err(e) => panic!("Failed to instantiate Discord Client: {e}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
Client { serenity_client }
|
Client {
|
||||||
|
serenity_client,
|
||||||
|
database_client,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start(&mut self) {
|
pub async fn start(&mut self) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
pub mod bulk_create_tag;
|
mod bulk_create_tag;
|
||||||
pub mod create_tag;
|
pub mod commands;
|
||||||
pub mod delete_tag;
|
mod create_tag;
|
||||||
pub mod list_tags;
|
mod delete_tag;
|
||||||
pub mod source_code;
|
mod list_tags;
|
||||||
|
mod source_code;
|
||||||
|
|
49
src/discord/commands/commands.rs
Normal file
49
src/discord/commands/commands.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use serenity::{
|
||||||
|
async_trait,
|
||||||
|
builder::CreateInteractionResponseData,
|
||||||
|
model::prelude::{
|
||||||
|
command::{Command, CommandOptionType},
|
||||||
|
interaction::application_command::ApplicationCommandInteraction,
|
||||||
|
},
|
||||||
|
prelude::Context,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::database::Client as DatabaseClient;
|
||||||
|
|
||||||
|
pub struct BotCommandOption {
|
||||||
|
pub name: String,
|
||||||
|
pub description: String,
|
||||||
|
pub kind: CommandOptionType,
|
||||||
|
pub required: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait BotCommand {
|
||||||
|
fn new(context: ApplicationCommandInteraction) -> Self;
|
||||||
|
fn name() -> String;
|
||||||
|
fn description() -> String;
|
||||||
|
fn options_list() -> Vec<BotCommandOption>;
|
||||||
|
async fn run(&self, response: &mut CreateInteractionResponseData, database: &DatabaseClient);
|
||||||
|
|
||||||
|
async fn register(context: &Context) {
|
||||||
|
match Command::create_global_application_command(context, |command| {
|
||||||
|
let mut new_command = command.name(Self::name()).description(Self::description());
|
||||||
|
|
||||||
|
for opt in Self::options_list() {
|
||||||
|
new_command = new_command.create_option(|option| {
|
||||||
|
option
|
||||||
|
.name(opt.name)
|
||||||
|
.description(opt.description)
|
||||||
|
.kind(opt.kind)
|
||||||
|
.required(opt.required)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
new_command
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(_) => println!("Successfully registered the {} command", Self::name()),
|
||||||
|
Err(_) => panic!("Failed to register the {} command", Self::name()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
use mongodb::bson::doc;
|
use mongodb::bson::doc;
|
||||||
|
|
||||||
use serenity::{
|
use serenity::{
|
||||||
builder::{CreateApplicationCommand, CreateInteractionResponseData},
|
async_trait,
|
||||||
|
builder::CreateInteractionResponseData,
|
||||||
model::{
|
model::{
|
||||||
application::interaction::application_command::ApplicationCommandInteraction,
|
application::interaction::application_command::ApplicationCommandInteraction,
|
||||||
prelude::{
|
prelude::{
|
||||||
|
@ -12,25 +13,38 @@ use serenity::{
|
||||||
|
|
||||||
use crate::database::{models::Tag, Client as DatabaseClient};
|
use crate::database::{models::Tag, Client as DatabaseClient};
|
||||||
|
|
||||||
pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand {
|
use super::commands::{BotCommand, BotCommandOption};
|
||||||
command
|
|
||||||
.name("create_tag")
|
struct CreateTagCommand {
|
||||||
.description("Add a new tag")
|
context: ApplicationCommandInteraction,
|
||||||
.create_option(|option| {
|
|
||||||
option
|
|
||||||
.name("tag")
|
|
||||||
.description("The tag to create")
|
|
||||||
.kind(CommandOptionType::String)
|
|
||||||
.required(true)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run<'a, 'b>(
|
#[async_trait]
|
||||||
response: &'a mut CreateInteractionResponseData<'b>,
|
impl BotCommand for CreateTagCommand {
|
||||||
command: &ApplicationCommandInteraction,
|
fn name() -> String {
|
||||||
database: &DatabaseClient,
|
String::from("create_tag")
|
||||||
) -> &'a mut CreateInteractionResponseData<'b> {
|
}
|
||||||
let arg = command
|
|
||||||
|
fn description() -> String {
|
||||||
|
String::from("Create a new tag")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn options_list() -> Vec<BotCommandOption> {
|
||||||
|
vec![BotCommandOption {
|
||||||
|
name: String::from("tag"),
|
||||||
|
description: String::from("The tag to create"),
|
||||||
|
kind: CommandOptionType::String,
|
||||||
|
required: true,
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new(context: ApplicationCommandInteraction) -> Self {
|
||||||
|
CreateTagCommand { context }
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run(&self, response: &mut CreateInteractionResponseData, database: &DatabaseClient) {
|
||||||
|
let arg = self
|
||||||
|
.context
|
||||||
.data
|
.data
|
||||||
.options
|
.options
|
||||||
.get(0)
|
.get(0)
|
||||||
|
@ -39,7 +53,8 @@ pub async fn run<'a, 'b>(
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("Could not deserialize option");
|
.expect("Could not deserialize option");
|
||||||
|
|
||||||
let guild_id = command
|
let guild_id = self
|
||||||
|
.context
|
||||||
.guild_id
|
.guild_id
|
||||||
.expect("Could not fetch guild id")
|
.expect("Could not fetch guild id")
|
||||||
.to_string();
|
.to_string();
|
||||||
|
@ -67,6 +82,5 @@ pub async fn run<'a, 'b>(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
response
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,17 @@
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::database::Client as DatabaseClient;
|
use crate::database::Client as DatabaseClient;
|
||||||
use serenity::{
|
use serenity::{
|
||||||
async_trait,
|
async_trait,
|
||||||
model::gateway::Ready,
|
model::gateway::Ready,
|
||||||
model::{
|
model::prelude::{interaction::Interaction, ResumedEvent},
|
||||||
application::command::Command,
|
|
||||||
prelude::{
|
|
||||||
interaction::{Interaction, InteractionResponseType},
|
|
||||||
ResumedEvent,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
prelude::{Context, EventHandler},
|
prelude::{Context, EventHandler},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::commands::*;
|
|
||||||
|
|
||||||
const MAX_ARGS_NUMBER: u32 = 25;
|
const MAX_ARGS_NUMBER: u32 = 25;
|
||||||
|
|
||||||
pub struct Handler {
|
pub struct Handler {
|
||||||
pub database: DatabaseClient,
|
pub database: Arc<Mutex<DatabaseClient>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
@ -25,21 +19,7 @@ impl EventHandler for Handler {
|
||||||
async fn ready(&self, ctx: Context, ready: Ready) {
|
async fn ready(&self, ctx: Context, ready: Ready) {
|
||||||
println!("Successfully connected as {}", ready.user.name);
|
println!("Successfully connected as {}", ready.user.name);
|
||||||
|
|
||||||
match Command::set_global_application_commands(&ctx.http, |commands| {
|
// TODO: Register commands
|
||||||
commands
|
|
||||||
.create_application_command(|command| source_code::register(command))
|
|
||||||
.create_application_command(|command| create_tag::register(command))
|
|
||||||
.create_application_command(|command| {
|
|
||||||
bulk_create_tag::register(command, MAX_ARGS_NUMBER)
|
|
||||||
})
|
|
||||||
.create_application_command(|command| delete_tag::register(command))
|
|
||||||
.create_application_command(|command| list_tags::register(command))
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(_) => println!("Successfully registered application commands"),
|
|
||||||
Err(e) => println!("Failed to register application commands: {e}"),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn resume(&self, _: Context, _: ResumedEvent) {
|
async fn resume(&self, _: Context, _: ResumedEvent) {
|
||||||
|
@ -49,21 +29,6 @@ impl EventHandler for Handler {
|
||||||
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
|
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
|
||||||
if let Interaction::ApplicationCommand(command) = interaction {
|
if let Interaction::ApplicationCommand(command) = interaction {
|
||||||
println!("Received command {}", command.data.name);
|
println!("Received command {}", command.data.name);
|
||||||
|
|
||||||
if let Err(e) = command
|
|
||||||
.create_interaction_response(&ctx.http, |response| {
|
|
||||||
response
|
|
||||||
.kind(InteractionResponseType::ChannelMessageWithSource)
|
|
||||||
.interaction_response_data(|message| match command.data.name.as_str() {
|
|
||||||
"source_code" => source_code::run(message),
|
|
||||||
"create_tag" => create_tag::run(message, &command, &self.database),
|
|
||||||
_ => message.content("Not yet implemented"),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
println!("Failed to answer to command: {e}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue