more todo commands
This commit is contained in:
parent
9574283638
commit
09b09c06b2
@ -13,9 +13,21 @@ use serenity::{
|
||||
framework::standard::CommandResult,
|
||||
};
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use crate::SQLPool;
|
||||
use sqlx::MySqlPool;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct TodoNotFound;
|
||||
|
||||
impl std::error::Error for TodoNotFound {}
|
||||
impl fmt::Display for TodoNotFound {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Todo not found")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Todo {
|
||||
@ -33,6 +45,18 @@ struct TodoTarget {
|
||||
}
|
||||
|
||||
impl TodoTarget {
|
||||
pub fn name(&self) -> String {
|
||||
if self.channel.is_some() {
|
||||
"Channel"
|
||||
}
|
||||
else if self.guild.is_some() {
|
||||
"Guild"
|
||||
}
|
||||
else {
|
||||
"User"
|
||||
}.to_string()
|
||||
}
|
||||
|
||||
pub async fn view(&self, pool: MySqlPool) -> Result<Vec<Todo>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
Ok(if let Some(cid) = self.channel {
|
||||
sqlx::query_as!(Todo,
|
||||
@ -53,7 +77,7 @@ SELECT * FROM todos WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?) AND
|
||||
else {
|
||||
sqlx::query_as!(Todo,
|
||||
"
|
||||
SELECT * FROM todos WHERE user_id = (SELECT id FROM users WHERE user = ?)
|
||||
SELECT * FROM todos WHERE user_id = (SELECT id FROM users WHERE user = ?) AND guild_id IS NULL
|
||||
", self.user.as_u64())
|
||||
.fetch_all(&pool)
|
||||
.await?
|
||||
@ -101,16 +125,22 @@ INSERT INTO todos (user_id, value) VALUES (
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn remove(&self, num: u32, pool: MySqlPool) -> Result<(), Box<dyn std::error::Error + Sync + Send>> {
|
||||
pub async fn remove(&self, num: usize, pool: MySqlPool) -> Result<(), Box<dyn std::error::Error + Sync + Send>> {
|
||||
let todos = self.view(pool.clone()).await?;
|
||||
|
||||
if let Some(removal_todo) = todos.get(num) {
|
||||
sqlx::query!(
|
||||
"
|
||||
DELETE FROM todos WHERE id = (SELECT id FROM (SELECT id FROM todos LIMIT ?,1) AS t)
|
||||
", num)
|
||||
DELETE FROM todos WHERE id = ?
|
||||
", removal_todo.id)
|
||||
.execute(&pool)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
else {
|
||||
Err(Box::try_from(TodoNotFound).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn clear(&self, pool: MySqlPool) -> Result<(), Box<dyn std::error::Error + Sync + Send>> {
|
||||
if let Some(cid) = self.channel {
|
||||
@ -132,7 +162,7 @@ DELETE FROM todos WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?) AND c
|
||||
else {
|
||||
sqlx::query!(
|
||||
"
|
||||
DELETE FROM todos WHERE user_id = (SELECT id FROM users WHERE user = ?)
|
||||
DELETE FROM todos WHERE user_id = (SELECT id FROM users WHERE user = ?) AND guild_id IS NULL
|
||||
", self.user.as_u64())
|
||||
.execute(&pool)
|
||||
.await?;
|
||||
@ -197,7 +227,7 @@ async fn todo_parse(ctx: &Context, msg: &Message, args: String) -> CommandResult
|
||||
};
|
||||
|
||||
if let Some(subcommand) = subcommand_opt {
|
||||
todo(ctx, target, subcommand, "".to_string()).await;
|
||||
todo(ctx, msg, target, subcommand, split.collect::<Vec<&str>>().join(" ")).await;
|
||||
}
|
||||
else {
|
||||
let _ = msg.channel_id.say(&ctx, "Todo help").await;
|
||||
@ -216,25 +246,65 @@ async fn todo_parse(ctx: &Context, msg: &Message, args: String) -> CommandResult
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn todo(ctx: &Context, target: TodoTarget, subcommand: SubCommand, extra: String) {
|
||||
async fn todo(ctx: &Context, msg: &Message, target: TodoTarget, subcommand: SubCommand, extra: String) {
|
||||
let pool = ctx.data.read().await
|
||||
.get::<SQLPool>().cloned().expect("Could not get SQLPool from data");
|
||||
|
||||
match subcommand {
|
||||
SubCommand::View => {
|
||||
println!("{:?}", target.view(pool).await.unwrap());
|
||||
let todo_items = target.view(pool).await.unwrap();
|
||||
let mut todo_groups = vec!["".to_string()];
|
||||
let mut char_count: u16 = 0;
|
||||
|
||||
todo_items.iter().enumerate().for_each(|(count, todo)| {
|
||||
let display = format!("{}: {}\n", count + 1, todo.value);
|
||||
|
||||
if char_count + display.len() as u16 > 2000 {
|
||||
char_count = display.len() as u16;
|
||||
|
||||
todo_groups.push(display);
|
||||
}
|
||||
else {
|
||||
char_count += display.len() as u16;
|
||||
|
||||
let last_group = todo_groups.pop().unwrap();
|
||||
|
||||
todo_groups.push(format!("{}{}", last_group, display));
|
||||
}
|
||||
});
|
||||
|
||||
for group in todo_groups {
|
||||
let _ = msg.channel_id.send_message(&ctx, |m| m
|
||||
.embed(|e| e
|
||||
.title(format!("{} Todo", target.name()))
|
||||
.description(group)
|
||||
)
|
||||
).await;
|
||||
}
|
||||
},
|
||||
|
||||
SubCommand::Add => {
|
||||
target.add(extra, pool).await.unwrap();
|
||||
|
||||
let _ = msg.channel_id.say(&ctx, "Todo added").await;
|
||||
},
|
||||
|
||||
SubCommand::Remove => {
|
||||
|
||||
let _ = if let Ok(num) = extra.parse::<usize>() {
|
||||
if target.remove(num - 1, pool).await.is_ok() {
|
||||
msg.channel_id.say(&ctx, "Todo removed")
|
||||
}
|
||||
else {
|
||||
msg.channel_id.say(&ctx, "Todo not removed")
|
||||
}
|
||||
}
|
||||
else {
|
||||
msg.channel_id.say(&ctx, "Todo not removed")
|
||||
}.await;
|
||||
},
|
||||
|
||||
SubCommand::Clear => {
|
||||
|
||||
target.clear(pool).await.unwrap();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
.add_command("help", &info_cmds::HELP_COMMAND)
|
||||
.add_command("info", &info_cmds::INFO_COMMAND)
|
||||
.add_command("donate", &info_cmds::DONATE_COMMAND)
|
||||
.add_command("todo", &todo_cmds::TODO_PARSE_COMMAND)
|
||||
.build();
|
||||
|
||||
let mut client = Client::new(&env::var("DISCORD_TOKEN").expect("Missing DISCORD_TOKEN from environment"))
|
||||
|
Loading…
Reference in New Issue
Block a user