115 lines
2.9 KiB
Rust
115 lines
2.9 KiB
Rust
use anyhow::Result;
|
|
use colored::Colorize;
|
|
|
|
use crate::cli::{AddArgs, Command, DoneArgs, EditArgs, ListArgs, RemoveArgs};
|
|
use crate::db::{self, ListFilters, Pool};
|
|
use crate::display::{print_todo, print_todo_list};
|
|
|
|
pub struct Ctx<'a> {
|
|
pub pool: &'a Pool,
|
|
}
|
|
|
|
pub async fn run(cmd: Command, ctx: &Ctx<'_>) -> Result<()> {
|
|
match cmd {
|
|
Command::Add(args) => add(ctx, args).await,
|
|
Command::List(args) => list(ctx, args).await,
|
|
Command::Done(args) => done(ctx, args).await,
|
|
Command::Edit(args) => edit(ctx, args).await,
|
|
Command::Remove(args) => remove(ctx, args).await,
|
|
Command::Tags => tags(ctx).await,
|
|
Command::Purge => purge(ctx).await,
|
|
Command::McpServe => crate::mcp::serve(ctx.pool).await,
|
|
}
|
|
}
|
|
|
|
async fn add(ctx: &Ctx<'_>, args: AddArgs) -> Result<()> {
|
|
let project = if args.no_project {
|
|
None
|
|
} else {
|
|
db::detect_project()
|
|
};
|
|
|
|
let todo =
|
|
db::insert_todo(ctx.pool, &args.text, &args.priority, project.as_deref(), &args.tag)
|
|
.await?;
|
|
print!("{} ", "added:".green().bold());
|
|
print_todo(&todo);
|
|
Ok(())
|
|
}
|
|
|
|
async fn list(ctx: &Ctx<'_>, args: ListArgs) -> Result<()> {
|
|
let project = if args.here {
|
|
db::detect_project()
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let todos = db::list_todos(
|
|
ctx.pool,
|
|
ListFilters {
|
|
tags: &args.tag,
|
|
priority: args.priority.as_ref(),
|
|
search: args.search.as_deref(),
|
|
project: project.as_deref(),
|
|
include_done: args.all,
|
|
},
|
|
)
|
|
.await?;
|
|
|
|
if args.json {
|
|
println!("{}", serde_json::to_string(&todos)?);
|
|
} else {
|
|
print_todo_list(&todos);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
async fn done(ctx: &Ctx<'_>, args: DoneArgs) -> Result<()> {
|
|
for id in args.id {
|
|
let todo = db::complete_todo(ctx.pool, id).await?;
|
|
print!("{} ", "done:".green().bold());
|
|
print_todo(&todo);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
async fn tags(ctx: &Ctx<'_>) -> Result<()> {
|
|
let tags = db::list_tags(ctx.pool).await?;
|
|
if tags.is_empty() {
|
|
println!("{}", "no tags".dimmed());
|
|
} else {
|
|
for tag in &tags {
|
|
println!(" {}", format!("#{tag}").blue());
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
async fn edit(ctx: &Ctx<'_>, args: EditArgs) -> Result<()> {
|
|
let todo = db::update_todo(
|
|
ctx.pool,
|
|
args.id,
|
|
args.text.as_deref(),
|
|
args.priority.as_ref(),
|
|
&args.tag,
|
|
&args.untag,
|
|
)
|
|
.await?;
|
|
print!("{} ", "edited:".green().bold());
|
|
print_todo(&todo);
|
|
Ok(())
|
|
}
|
|
|
|
async fn remove(ctx: &Ctx<'_>, args: RemoveArgs) -> Result<()> {
|
|
let todo = db::delete_todo(ctx.pool, args.id).await?;
|
|
print!("{} ", "removed:".red().bold());
|
|
print_todo(&todo);
|
|
Ok(())
|
|
}
|
|
|
|
async fn purge(ctx: &Ctx<'_>) -> Result<()> {
|
|
let count = db::purge_completed(ctx.pool).await?;
|
|
println!("{}", format!("purged {count} completed todo(s)").dimmed());
|
|
Ok(())
|
|
}
|