diff --git a/Cargo.toml b/Cargo.toml index 6481ef4..520786f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" [dependencies] poise = "0.5.5" +tokio = { version = "1.21.1", features = ["full"] } \ No newline at end of file diff --git a/src/data_loader.rs b/src/data_loader.rs index 6661ebf..7ddc2cd 100644 --- a/src/data_loader.rs +++ b/src/data_loader.rs @@ -1,20 +1,20 @@ use std::{io::prelude::*, fs::File, path::Path }; -pub fn load_token(file_name: &str) -> String +pub fn load_token(file_name: &str) -> Result { let mut file = match File::open(Path::new(file_name)) { Ok(file) => file, - Err(why) => panic!("Could not open token file {}: {}", Path::new(file_name).display(), why), + Err(why) => return Err(format!("Could not open token file {}: {}", Path::new(file_name).display(), why)), }; let mut s = String::new(); let token = match file.read_to_string(&mut s) { - Err(why) => panic!("couldn't read {}: {}", Path::new(file_name).display(), why), + Err(why) => return Err(format!("couldn't read {}: {}", Path::new(file_name).display(), why)), Ok(_) => s, }; - token + Ok(token) } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index a0cbe23..93af13a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,76 @@ +use poise::serenity_prelude as serenity; + mod commands; mod data_loader; -fn main() +pub struct Data {} // User data, which is stored and accessible in all command invocations +type Error = Box; +type Context<'a> = poise::Context<'a, Data, Error>; + +/// Displays your or another user's account creation date +#[poise::command(slash_command, prefix_command)] +async fn age(ctx: Context<'_>, #[description = "Selected user"] user: Option) -> Result<(), Error> +{ + let u = user.as_ref().unwrap_or_else(|| ctx.author()); + let response = format!("{}'s account was created at {}", u.name, u.created_at()); + ctx.say(response).await?; + Ok(()) +} + +/// A command with two subcommands: `child1` and `child2` +/// +/// Running this function directly, without any subcommand, is only supported in prefix commands. +/// Discord doesn't permit invoking the root command of a slash command if it has subcommands. +#[poise::command(prefix_command, slash_command, subcommands("child1", "child2"))] +pub async fn parent(ctx: Context<'_>) -> Result<(), Error> +{ + ctx.say("Hello there!").await?; + Ok(()) +} + +/// A subcommand of `parent` +#[poise::command(prefix_command, slash_command)] +pub async fn child1(ctx: Context<'_>) -> Result<(), Error> { - let token = data_loader::load_token("secrets/test.txt"); - println!("test data: {}", token); + ctx.say("You invoked the first child command!").await?; + Ok(()) +} + +/// Another subcommand of `parent` +#[poise::command(prefix_command, slash_command)] +pub async fn child2(ctx: Context<'_>) -> Result<(), Error> +{ + ctx.say("You invoked the second child command!").await?; + Ok(()) +} + +#[tokio::main] +async fn main() +{ + let token = match data_loader::load_token("secrets/test.txt") + { + Ok(t) => t, + Err(why) => panic!("Could not load app token: {}", why), + }; + + println!("Connecting..."); + + let framework = poise::Framework::builder() + .options(poise::FrameworkOptions { + commands: vec![age(), parent()], + ..Default::default() + }) + .token(token) + .intents(serenity::GatewayIntents::non_privileged()) + .setup(|ctx, _ready, framework| + { + Box::pin(async move + { + poise::builtins::register_globally(ctx, &framework.options().commands).await?; + Ok(Data {}) + }) + }); + framework.run().await.unwrap(); }