use super::funejson::Value; use super::dates_day_of_week::day_of_week; use super::math_round_div::round_div; use super::todo_due_status::due_status; use super::todo_item::Todo; use super::todo_item_validate_todo::todos_from_value; /// Counts for a todo list. percent_done rounds down so 100 means everything /// is done; overdue and due_today agree with due_status. /// /// # Panics /// Panics on an impossible or malformed date. pub fn summarise_todos(todos: &[Todo], today: &str) -> TodoSummary { day_of_week(today); // a bad today is an error even for an empty list let mut done = 0; let mut overdue = 0; let mut due_today = 0; for todo in todos { let status = due_status(todo, today); if todo.done { done += 1; } if status == "overdue" { overdue += 1; } if status == "today" { due_today += 1; } } let total = todos.len() as i64; let active = total - done; TodoSummary { total, active, done, overdue, due_today, percent_done: if total == 0 { 0 } else { round_div(done * 100, total, "down") }, items_left: if active == 1 { "1 item left".to_string() } else { format!("{} items left", active) }, } } pub fn todo_summary_to_value(s: &TodoSummary) -> Value { Value::obj(vec![ ("total", Value::Int(s.total)), ("active", Value::Int(s.active)), ("done", Value::Int(s.done)), ("overdue", Value::Int(s.overdue)), ("dueToday", Value::Int(s.due_today)), ("percentDone", Value::Int(s.percent_done)), ("itemsLeft", Value::str(&s.items_left)), ]) } pub fn fune_vector(args: &[Value]) -> Value { todo_summary_to_value(&summarise_todos(&todos_from_value(&args[0]), args[1].as_str())) }