mps-rs 1.6.0

MPS — plain-text personal productivity CLI (Rust)
Documentation
use std::collections::HashMap;
use anyhow::{bail, Result};
use chrono::{Local, NaiveDate};
use colored::Colorize;
use crate::config::Config;
use crate::date_parse;
use crate::store::Store;

/// Update an element's typed attributes in-place.
pub fn run(
    config:     &Config,
    ref_path:   &str,
    status:     Option<String>,
    start_time: Option<String>,
    end_time:   Option<String>,
    at:         Option<String>,
    date:       Option<String>,
) -> Result<()> {
    let mut new_attrs: HashMap<String, String> = HashMap::new();
    if let Some(s) = status     { new_attrs.insert("status".into(), s); }
    if let Some(s) = start_time { new_attrs.insert("start".into(),  s); }
    if let Some(e) = end_time   { new_attrs.insert("end".into(),    e); }
    if let Some(a) = at         { new_attrs.insert("at".into(),     a); }

    if new_attrs.is_empty() {
        bail!("No attributes specified. Use --status, --start-time, --end-time, or --at.");
    }

    let d = resolve_date(date)?;
    let store = Store::new(&config.storage_dir);

    match store.rewrite_element(ref_path, &new_attrs, d)? {
        true  => println!("  {} {}", "updated".green(), ref_path),
        false => bail!("Could not update '{}'. Check the ref is correct.", ref_path),
    }
    Ok(())
}

/// Mark a task as done — shorthand for `update REFPATH --status done`.
pub fn run_done(
    config:   &Config,
    ref_path: &str,
    date:     Option<String>,
) -> Result<()> {
    let mut new_attrs = HashMap::new();
    new_attrs.insert("status".into(), "done".into());

    let d = store_date(date)?;
    let store = Store::new(&config.storage_dir);

    match store.rewrite_element(ref_path, &new_attrs, d)? {
        true  => println!("  {} {}", "done".green(), ref_path),
        false => bail!("Could not mark '{}' as done. Check the ref is correct.", ref_path),
    }
    Ok(())
}

fn resolve_date(date: Option<String>) -> Result<NaiveDate> {
    match date {
        Some(s) => Ok(date_parse::parse_date(&s)?),
        None    => Ok(Local::now().date_naive()),
    }
}

fn store_date(date: Option<String>) -> Result<NaiveDate> {
    resolve_date(date)
}