diff --git a/Cargo.toml b/Cargo.toml index 4d21a33..91561bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,12 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +async-trait = "0.1.42" itertools = "0.10.0" lazy_static = "1.4.0" redis = "0.20.0" serde = { version = "1.0.123", features = ["derive"] } serde_json = "1.0.62" -serenity = "0.8.6" +serenity = "0.10.5" time = "0.2.10" +tokio = { version = "1.2.0", features = ["full"] } diff --git a/src/main.rs b/src/main.rs index 5050f81..98a92c2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,11 @@ +use async_trait::async_trait; use inbox::*; use itertools::Itertools; use lazy_static::lazy_static; use serenity::client::Client; use serenity::framework::standard::{ macros::{command, group}, - CommandError, CommandResult, StandardFramework, + CommandResult, StandardFramework, }; use serenity::model::{ channel::Message, @@ -36,12 +37,15 @@ macro_rules! send_or_log { #[commands(name, message, question, inbox)] struct Fluff; struct Handler; +#[async_trait] impl EventHandler for Handler { - fn guild_ban_addition(&self, ctx: Context, guild_id: GuildId, _: User) { + async fn guild_ban_addition(&self, ctx: Context, guild_id: GuildId, _: User) { if guild_id == 427456811973738498 { - send_or_log!( - ChannelId(562731470423064587).say(&ctx, "Dies ist eine flauschige Diktatur!") - ); + send_or_log!({ + ChannelId(562731470423064587) + .say(&ctx, "Dies ist eine flauschige Diktatur!") + .await + }); } } } @@ -51,30 +55,34 @@ fn read_token() -> io::Result { reader.lines().next().unwrap() } -fn main() { - let mut client = Client::new(&read_token().expect("no secret file"), Handler) +#[tokio::main] +async fn main() { + let mut client = Client::builder(&read_token().expect("no secret file")) + .event_handler(Handler) + .framework( + StandardFramework::new() + .configure(|c| c.prefix("!")) + .group(&FLUFF_GROUP), + ) + .await .expect("Error creating client"); - client.with_framework( - StandardFramework::new() - .configure(|c| c.prefix("!")) - .group(&FLUFF_GROUP), - ); INBOX.count_messages("test"); // initialize the lazy static so we know if redis is unavailable - if let Err(why) = client.start() { + if let Err(why) = client.start().await { println!("An error occurred while running the client: {:?}", why); } } #[command] -fn name(ctx: &mut Context, msg: &Message) -> CommandResult { +async fn name(ctx: &Context, msg: &Message) -> CommandResult { if let Some((_, name)) = msg.content.split_once(' ') { let (name, adjustment) = name.split_once(" -").unwrap_or((name, "0")); let adjustment = adjustment.strip_suffix("h").unwrap_or(adjustment); msg.guild(&ctx) + .await .unwrap() - .read() - .edit_member(&ctx, msg.author.id, |m| m.nickname(name))?; + .edit_member(&ctx, msg.author.id, |m| m.nickname(name)) + .await?; let now = time::OffsetDateTime::now_utc() - adjustment .parse::() @@ -91,47 +99,54 @@ fn name(ctx: &mut Context, msg: &Message) -> CommandResult { now.unix_timestamp() ); } else { - return Err(CommandError(String::from("Please specify a new name."))); + send_or_log!(msg.reply(&ctx, "Please specify a new name.").await); } Ok(()) } #[command] -fn inbox(ctx: &mut Context, msg: &Message) -> CommandResult { +async fn inbox(ctx: &Context, msg: &Message) -> CommandResult { if msg.author.id != INBOX_OWNER { - send_or_log!(msg.reply(&ctx, "You don’t have the permission to do that")); + send_or_log!( + msg.reply(&ctx, "You don’t have the permission to do that") + .await + ); return Ok(()); } if let Some((_, name)) = msg.content.split_once(' ') { let messages = INBOX.fetch_messages(name); if messages.is_empty() { - send_or_log!(msg.reply(&ctx, format!("Keine neuen Nachrichten für {}.", name))); + send_or_log!( + msg.reply(&ctx, format!("Keine neuen Nachrichten für {}.", name)) + .await + ); return Ok(()); } let output = messages.into_iter().join("\n"); - send_or_log!(msg.reply(&ctx, output)); + send_or_log!(msg.reply(&ctx, output).await); } else { - send_or_log!(msg.reply(&ctx, "Kein Name für die Abfrage.")); + send_or_log!(msg.reply(&ctx, "Kein Name für die Abfrage.").await); } Ok(()) } #[command] -fn message(ctx: &mut Context, msg: &Message) -> CommandResult { - message_internal(ctx, msg, &msg.content) +async fn message(ctx: &Context, msg: &Message) -> CommandResult { + message_internal(ctx, msg, &msg.content).await } #[command] -fn question(ctx: &mut Context, msg: &Message) -> CommandResult { +async fn question(ctx: &Context, msg: &Message) -> CommandResult { message_internal( ctx, msg, &msg.content.replacen("!question", "!message Stream:", 1), ) + .await } -fn message_internal(ctx: &mut Context, msg: &Message, content: &str) -> CommandResult { - InboxMessage::parse(content, msg.author.id) +async fn message_internal(ctx: &Context, msg: &Message, content: &str) -> CommandResult { + let result = InboxMessage::parse(content, msg.author.id) .ok_or_else(|| { String::from( "Nachricht konnte nicht gesendet werden. @@ -139,15 +154,16 @@ Bitte achte auf die richtige Formulierung: “!message : ”, z.B. “!message Lana: Hawwu!”", ) }) - .and_then(|m| INBOX.queue_message(&m)) - .map(|n| { - send_or_log!(msg.reply( + .and_then(|m| INBOX.queue_message(&m)); + match result { + Ok(name) => send_or_log!( + msg.reply( &ctx, - &format!("Deine Nachricht wurde erfolgreich an {} gesendet", n), - )); - }) - .map_err(|e| { - send_or_log!(msg.reply(&ctx, &e)); - CommandError(e) - }) + format!("Deine Nachricht wurde erfolgreich an {} gesendet", name), + ) + .await + ), + Err(e) => send_or_log!(msg.reply(&ctx, e).await), + }; + Ok(()) }