tasks-cli-rs 0.1.1

Markdown-based TODO task management CLI: each task is a Markdown file with YAML front matter
use clap::Parser;

mod cli;
mod commands;
mod config;
mod editor;
mod error;
mod filter;
mod library;
mod model;
mod storage;

fn main() {
    let cli = cli::Cli::parse();
    if let Err(err) = run(cli) {
        eprintln!("error: {err}");
        std::process::exit(1);
    }
}

fn run(cli: cli::Cli) -> error::Result<()> {
    match cli.command {
        cli::Command::Info => {
            let config = config::Config::load()?;
            println!("base dir: {}", config::base_dir()?.display());
            println!("editor:   {}", config.editor.as_deref().unwrap_or("(auto)"));
        }
        cli::Command::Lib { command } => commands::lib::run(command)?,
        cli::Command::New { title, priority, tags, due, dir } => {
            commands::task::new(title, priority, tags, due, dir)?
        }
        cli::Command::List { dir, status, tag, priority, due_before, due_after } => {
            commands::task::list(commands::task::ListArgs {
                dir,
                status,
                tag,
                priority,
                due_before,
                due_after,
            })?
        }
        cli::Command::Search { query, status, tag } => {
            commands::task::search(query, status, tag)?
        }
        cli::Command::Tag { command } => match command {
            cli::TagCommand::Add { id, tags } => commands::task::tag_add(&id, tags)?,
            cli::TagCommand::Remove { id, tags } => commands::task::tag_remove(&id, tags)?,
            cli::TagCommand::List => commands::task::tag_list()?,
        },
        cli::Command::Show { id } => commands::task::show(&id)?,
        cli::Command::Delete { id, force } => commands::task::delete(&id, force)?,
        cli::Command::Start { id } => commands::task::set_status(&id, model::Status::InProgress)?,
        cli::Command::Done { id } => commands::task::set_status(&id, model::Status::Done)?,
        cli::Command::Cancel { id } => commands::task::set_status(&id, model::Status::Cancelled)?,
        cli::Command::Status { id, status } => {
            let status = status
                .parse::<model::Status>()
                .map_err(error::Error::InvalidTaskFile)?;
            commands::task::set_status(&id, status)?
        }
        cli::Command::Set { id, title, priority, due, tag_add, tag_remove } => {
            commands::task::set_fields(&id, title, priority, due, tag_add, tag_remove)?
        }
        cli::Command::Edit { id, editor, lib } => commands::task::edit(id, editor, lib)?,
    }
    Ok(())
}