use crate::{ util::{ debug_say, operators::{get_china_ops, get_global_ops, Operator}, }, DbConnPool, }; use pity::{pity, PITY_COMMAND}; use queries::OpCommandQueries; use serenity::framework::standard::{macros::command, Args, CommandResult}; use serenity::model::{channel::Message, id::UserId}; use serenity::prelude::Context; use std::{collections::HashSet, str::FromStr}; mod pity; mod queries; #[command] #[sub_commands(list, add, remove, missing, roll, pity)] async fn op(_: &Context, _: &Message) -> CommandResult { Ok(()) } #[command] async fn list(ctx: &Context, msg: &Message, args: Args) -> CommandResult { let db_pool = ctx.data.clone(); let db_pool = db_pool.read().await; let db_pool = db_pool .get::() .expect("No db pool in context?!"); let user_id = match args.current().map(|id| UserId::from_str(id.trim())) { Some(Ok(user_id)) => user_id, _ => msg.author.id, } .as_u64() .to_string(); debug_say( msg, ctx, format!( "{}'s 6\u{2605} Operators:\n{}", msg.author, db_pool .get_operators(user_id) .await? .iter() .map(|(op, pot)| format!("{:?} (Pot {})", op, pot)) .collect::>() .join("\n") ), ) .await?; Ok(()) } #[command] async fn add(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { let db_pool = ctx.data.clone(); let db_pool = db_pool.read().await; let db_pool = db_pool .get::() .expect("No db pool in context?!"); let mut failed_parses = false; let mut num_added: usize = 0; for arg in args.iter::() { match arg { Ok(op) => { db_pool .add_operator(msg.author.id.as_u64().to_string(), op) .await?; num_added += 1; } Err(_) => { failed_parses = true; } }; } if failed_parses { debug_say( msg, ctx, "Unable to add some operators. Check your spelling and try again.", ) .await?; } match num_added { 0 => debug_say(msg, ctx, "Didn't add any operators...").await?, 1 => debug_say(msg, ctx, "Added an operator!").await?, n => debug_say(msg, ctx, format!("Added {} operators!", n)).await?, }; Ok(()) } #[command] async fn remove(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { let db_pool = ctx.data.clone(); let db_pool = db_pool.read().await; let db_pool = db_pool .get::() .expect("No db pool in context?!"); let mut failed_parses = false; let mut num_added: usize = 0; for arg in args.iter::() { match arg { Ok(op) => { db_pool .remove_operator(msg.author.id.as_u64().to_string(), op) .await?; num_added += 1; } Err(_) => { failed_parses = true; } }; } if failed_parses { debug_say( msg, ctx, "Unable to remove some operators. Check your spelling and try again.", ) .await?; } match num_added { 0 => debug_say(msg, ctx, "Didn't remove any operators...").await?, 1 => debug_say(msg, ctx, "Removed an operator!").await?, n => debug_say(msg, ctx, format!("Removed {} operators!", n)).await?, }; Ok(()) } #[command] async fn missing(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { let db_pool = ctx.data.clone(); let db_pool = db_pool.read().await; let db_pool = db_pool .get::() .expect("No db pool in context?!"); let user_id = match args.current().map(|id| UserId::from_str(id.trim())) { Some(Ok(user_id)) => user_id, _ => msg.author.id, } .as_u64() .to_string(); let operators = db_pool .get_operators(user_id) .await? .iter() .map(|(op, _)| *op) .collect::>(); let compare_ops = match args.single_quoted::() { Ok(arg) if arg == "china" || arg == "cn" => get_china_ops(), _ => get_global_ops(), }; let operators = operators .symmetric_difference(&compare_ops) .collect::>(); let resp = if operators.len() > 5 { format!( "Missing {} and {} more...", operators .iter() .take(5) .map(|op| format!("{:?}", op)) .collect::>() .join(", "), operators.len() - 5, ) } else { format!( "Missing {}", operators .iter() .map(|op| format!("{:?}", op)) .collect::>() .join(", ") ) }; debug_say(msg, ctx, resp).await?; Ok(()) } #[command] async fn roll(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { let db_pool = ctx.data.clone(); let db_pool = db_pool.read().await; let db_pool = db_pool .get::() .expect("No db pool in context?!"); if args.current().is_none() { args = Args::new("1", &[]); } while args.current().is_some() { match args.quoted().current() { Some(amt) if amt.parse::().is_ok() => { db_pool .add_roll_count(msg.author.id.as_u64().to_string(), amt.parse().unwrap()) .await?; } Some(operator) if Operator::from_str(operator).is_ok() => { let new_op = Operator::from_str(operator).unwrap(); db_pool .add_operator(msg.author.id.as_u64().to_string(), new_op) .await?; debug_say(msg, ctx, format!("Congratulations on {:?}!", new_op)).await?; db_pool .reset_roll_count(msg.author.id.as_u64().to_string()) .await?; } _ => (), } args.advance(); } pity(ctx, msg, args).await?; Ok(()) }