more todo commands
This commit is contained in:
parent
9574283638
commit
09b09c06b2
@ -13,9 +13,21 @@ use serenity::{
|
|||||||
framework::standard::CommandResult,
|
framework::standard::CommandResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use crate::SQLPool;
|
use crate::SQLPool;
|
||||||
use sqlx::MySqlPool;
|
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)]
|
#[derive(Debug)]
|
||||||
struct Todo {
|
struct Todo {
|
||||||
@ -33,6 +45,18 @@ struct TodoTarget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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>> {
|
pub async fn view(&self, pool: MySqlPool) -> Result<Vec<Todo>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
Ok(if let Some(cid) = self.channel {
|
Ok(if let Some(cid) = self.channel {
|
||||||
sqlx::query_as!(Todo,
|
sqlx::query_as!(Todo,
|
||||||
@ -53,7 +77,7 @@ SELECT * FROM todos WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?) AND
|
|||||||
else {
|
else {
|
||||||
sqlx::query_as!(Todo,
|
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())
|
", self.user.as_u64())
|
||||||
.fetch_all(&pool)
|
.fetch_all(&pool)
|
||||||
.await?
|
.await?
|
||||||
@ -101,16 +125,22 @@ INSERT INTO todos (user_id, value) VALUES (
|
|||||||
Ok(())
|
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!(
|
sqlx::query!(
|
||||||
"
|
"
|
||||||
DELETE FROM todos WHERE id = (SELECT id FROM (SELECT id FROM todos LIMIT ?,1) AS t)
|
DELETE FROM todos WHERE id = ?
|
||||||
", num)
|
", removal_todo.id)
|
||||||
.execute(&pool)
|
.execute(&pool)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Err(Box::try_from(TodoNotFound).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn clear(&self, pool: MySqlPool) -> Result<(), Box<dyn std::error::Error + Sync + Send>> {
|
pub async fn clear(&self, pool: MySqlPool) -> Result<(), Box<dyn std::error::Error + Sync + Send>> {
|
||||||
if let Some(cid) = self.channel {
|
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 {
|
else {
|
||||||
sqlx::query!(
|
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())
|
", self.user.as_u64())
|
||||||
.execute(&pool)
|
.execute(&pool)
|
||||||
.await?;
|
.await?;
|
||||||
@ -197,7 +227,7 @@ async fn todo_parse(ctx: &Context, msg: &Message, args: String) -> CommandResult
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(subcommand) = subcommand_opt {
|
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 {
|
else {
|
||||||
let _ = msg.channel_id.say(&ctx, "Todo help").await;
|
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(())
|
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
|
let pool = ctx.data.read().await
|
||||||
.get::<SQLPool>().cloned().expect("Could not get SQLPool from data");
|
.get::<SQLPool>().cloned().expect("Could not get SQLPool from data");
|
||||||
|
|
||||||
match subcommand {
|
match subcommand {
|
||||||
SubCommand::View => {
|
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 => {
|
SubCommand::Add => {
|
||||||
|
target.add(extra, pool).await.unwrap();
|
||||||
|
|
||||||
|
let _ = msg.channel_id.say(&ctx, "Todo added").await;
|
||||||
},
|
},
|
||||||
|
|
||||||
SubCommand::Remove => {
|
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 => {
|
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("help", &info_cmds::HELP_COMMAND)
|
||||||
.add_command("info", &info_cmds::INFO_COMMAND)
|
.add_command("info", &info_cmds::INFO_COMMAND)
|
||||||
.add_command("donate", &info_cmds::DONATE_COMMAND)
|
.add_command("donate", &info_cmds::DONATE_COMMAND)
|
||||||
|
.add_command("todo", &todo_cmds::TODO_PARSE_COMMAND)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let mut client = Client::new(&env::var("DISCORD_TOKEN").expect("Missing DISCORD_TOKEN from environment"))
|
let mut client = Client::new(&env::var("DISCORD_TOKEN").expect("Missing DISCORD_TOKEN from environment"))
|
||||||
|
Loading…
Reference in New Issue
Block a user