🧰 Fixes and final important features
This commit is contained in:
parent
102123b688
commit
c08af0172c
36
src/args.rs
36
src/args.rs
@ -100,8 +100,36 @@ pub struct EditTask {
|
|||||||
pub struct ModifyTask {
|
pub struct ModifyTask {
|
||||||
/// ID of the task
|
/// ID of the task
|
||||||
pub id: usize,
|
pub id: usize,
|
||||||
/// Summary of the task
|
|
||||||
pub summary: String,
|
/// Title of the task
|
||||||
|
#[arg(short, long)]
|
||||||
|
#[clap(default_value=None)]
|
||||||
|
pub title: Option<String>,
|
||||||
|
|
||||||
|
/// Any notes to help explain/remember the task
|
||||||
|
#[arg(short, long)]
|
||||||
|
#[clap(default_value=None)]
|
||||||
|
pub notes: Option<String>,
|
||||||
|
|
||||||
|
/// Tags for organisation, separated by commas
|
||||||
|
#[arg(short, long)]
|
||||||
|
#[clap(default_value=None)]
|
||||||
|
pub tags: Option<String>,
|
||||||
|
|
||||||
|
/// Date when you want to do the task
|
||||||
|
#[arg(short, long)]
|
||||||
|
#[clap(default_value=None)]
|
||||||
|
pub when: Option<String>,
|
||||||
|
|
||||||
|
/// Deadline when the task has to be in
|
||||||
|
#[arg(short, long)]
|
||||||
|
#[clap(default_value=None)]
|
||||||
|
pub deadline: Option<String>,
|
||||||
|
|
||||||
|
/// The date and time when you want to be reminded
|
||||||
|
#[arg(short, long)]
|
||||||
|
#[clap(default_value=None)]
|
||||||
|
pub reminder: Option<String>,
|
||||||
}
|
}
|
||||||
#[derive(Args, PartialEq, Debug)]
|
#[derive(Args, PartialEq, Debug)]
|
||||||
pub struct GitExecute {
|
pub struct GitExecute {
|
||||||
@ -111,12 +139,12 @@ pub struct GitExecute {
|
|||||||
#[derive(Args, PartialEq, Debug)]
|
#[derive(Args, PartialEq, Debug)]
|
||||||
pub struct SyncTasks {
|
pub struct SyncTasks {
|
||||||
/// Git remote to use
|
/// Git remote to use
|
||||||
#[clap(default_value="origin")]
|
#[clap(default_value = "origin")]
|
||||||
pub remote: String,
|
pub remote: String,
|
||||||
}
|
}
|
||||||
#[derive(Args, PartialEq, Debug)]
|
#[derive(Args, PartialEq, Debug)]
|
||||||
pub struct UndoExecute {
|
pub struct UndoExecute {
|
||||||
/// Number of times to undo
|
/// Number of times to undo
|
||||||
#[clap(default_value="1")]
|
#[clap(default_value = "1")]
|
||||||
pub number: String,
|
pub number: String,
|
||||||
}
|
}
|
135
src/cli.rs
135
src/cli.rs
@ -1,72 +1,98 @@
|
|||||||
use chrono::{NaiveDateTime, Local};
|
use crate::args::{Commands, TasksArgs};
|
||||||
use crate::args::{TasksArgs, Commands};
|
use crate::args::{CompleteTask, CreateTask, DeleteTask, ShowTask, StartTask, StopTask, ModifyTask};
|
||||||
use crate::args::{CreateTask, DeleteTask, ShowTask, StartTask, StopTask, CompleteTask};
|
use crate::tasks::{Status, Task, Tasks, TasksError};
|
||||||
use crate::tasks::{Tasks, Task, Status, TasksError};
|
use chrono::{Local, NaiveDateTime};
|
||||||
use prettytable::{Table, Row, row, format};
|
|
||||||
use colored::*;
|
use colored::*;
|
||||||
use fuzzydate;
|
use fuzzydate;
|
||||||
|
use prettytable::{format, row, Row, Table};
|
||||||
use std::panic;
|
use std::panic;
|
||||||
|
|
||||||
|
|
||||||
fn success(msg: String) {
|
|
||||||
println!("{} {}", "success:".green().bold(), msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn warning(msg: &str) {
|
pub fn warning(msg: &str) {
|
||||||
println!("{} {}", "warning:".yellow().bold(), msg);
|
println!("{} {}", "warning:".yellow().bold(), msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn info(msg: &str) {
|
pub fn info(msg: String) {
|
||||||
println!("{} {}", "info:".blue().bold(), msg);
|
println!("{} {}", "info:".blue().bold(), msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn success(msg: String) {
|
||||||
|
println!("{} {}", "success:".green().bold(), msg);
|
||||||
|
}
|
||||||
|
|
||||||
fn task_msg(msg: &str, task: &Task, id: usize) -> String {
|
fn task_msg(msg: &str, task: &Task, id: usize) -> String {
|
||||||
format!("{} task: {}({})", msg, task.title.blue(), id.to_string().cyan())
|
format!(
|
||||||
|
"{} task: {}({})",
|
||||||
|
msg,
|
||||||
|
task.title.blue(),
|
||||||
|
id.to_string().cyan()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_date(date_string: Option<String>) -> Option<NaiveDateTime> {
|
fn parse_date(date_string: Option<String>) -> Option<NaiveDateTime> {
|
||||||
if date_string.is_some() {
|
if date_string.is_some() {
|
||||||
match fuzzydate::parse(date_string.unwrap()) {
|
match fuzzydate::parse(date_string.unwrap()) {
|
||||||
Ok(date) => Some(date),
|
Ok(date) => Some(date),
|
||||||
Err(err) => panic!("{:?}", err),
|
Err(err) => panic!("{} {:?}", "error:".red().bold(), err),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn date_to_string(date: &Option<NaiveDateTime>) -> ColoredString {
|
||||||
|
if date.is_some() {
|
||||||
|
let date = date.unwrap().date();
|
||||||
|
let date_string = format!("{}", date.format("%Y-%m-%d"));
|
||||||
|
let now = Local::now().date_naive();
|
||||||
|
|
||||||
|
if date <= now {
|
||||||
|
// If the date is today or past today
|
||||||
|
date_string.bright_red()
|
||||||
|
} else if now.succ_opt().unwrap() == date {
|
||||||
|
// If the date is tomorrow
|
||||||
|
date_string.yellow()
|
||||||
|
} else {
|
||||||
|
// Otherwise the date is too far in the past
|
||||||
|
date_string.white()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
"N/A".bright_black()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn calc_row(task: &Task, id: usize) -> Row {
|
fn calc_row(task: &Task, id: usize) -> Row {
|
||||||
if task.status == Status::Complete {
|
if task.status == Status::Complete {
|
||||||
// Generate greyed out rows for complete tasks
|
// Generate greyed out rows for complete tasks
|
||||||
Row::from([id.to_string().bright_black().italic(),
|
Row::from([
|
||||||
|
id.to_string().bright_black().italic(),
|
||||||
task.status.as_string().bright_black().italic(),
|
task.status.as_string().bright_black().italic(),
|
||||||
"N/A".bright_black(),
|
task.title.clone().bright_black().italic(),
|
||||||
task.title.clone().bright_black().italic()])
|
date_to_string(&task.when).bright_black().italic(),
|
||||||
|
date_to_string(&task.deadline).bright_black().italic(),
|
||||||
|
])
|
||||||
} else {
|
} else {
|
||||||
let when = if task.when.is_some() {
|
|
||||||
let date = format!("{}", task.when.unwrap().format("%Y-%m-%d"));
|
|
||||||
let now = Local::now().date_naive();
|
|
||||||
|
|
||||||
if now == task.when.unwrap().date() {
|
|
||||||
date.bright_red()
|
|
||||||
} else if now.succ_opt().unwrap() == task.when.unwrap().date() {
|
|
||||||
date.yellow()
|
|
||||||
} else {
|
|
||||||
date.white()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
"N/A".bright_black()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generate normal colored rows for uncompleted tasks
|
// Generate normal colored rows for uncompleted tasks
|
||||||
Row::from([id.to_string().cyan(), task.status.as_string(), when, task.title.clone().white()])
|
Row::from([
|
||||||
|
id.to_string().cyan(),
|
||||||
|
task.status.as_string(),
|
||||||
|
task.title.clone().white(),
|
||||||
|
date_to_string(&task.when),
|
||||||
|
date_to_string(&task.deadline),
|
||||||
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(tasks: &mut Tasks, arguments: TasksArgs) -> Result<&mut Tasks, TasksError> {
|
pub fn execute(tasks: &mut Tasks, arguments: TasksArgs) -> Result<&mut Tasks, TasksError> {
|
||||||
match arguments.command {
|
match arguments.command {
|
||||||
Commands::Add(CreateTask { title, notes, tags, when, deadline, reminder, ..}) => {
|
Commands::Add(CreateTask {
|
||||||
|
title,
|
||||||
|
notes,
|
||||||
|
tags,
|
||||||
|
when,
|
||||||
|
deadline,
|
||||||
|
reminder,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
let when = parse_date(when);
|
let when = parse_date(when);
|
||||||
let deadline = parse_date(deadline);
|
let deadline = parse_date(deadline);
|
||||||
let reminder = parse_date(reminder);
|
let reminder = parse_date(reminder);
|
||||||
@ -80,8 +106,30 @@ pub fn execute(tasks: &mut Tasks, arguments: TasksArgs) -> Result<&mut Tasks, Ta
|
|||||||
tasks.push(task.clone());
|
tasks.push(task.clone());
|
||||||
|
|
||||||
let id = tasks.len() - 1;
|
let id = tasks.len() - 1;
|
||||||
success(task_msg("created", &task, id));
|
|
||||||
|
|
||||||
|
success(task_msg("created", &task, id));
|
||||||
|
Ok(tasks)
|
||||||
|
}
|
||||||
|
|
||||||
|
Commands::Modify(ModifyTask { id, title, notes, tags, when, deadline, reminder }) => {
|
||||||
|
let when = parse_date(when);
|
||||||
|
let deadline = parse_date(deadline);
|
||||||
|
let reminder = parse_date(reminder);
|
||||||
|
let tags: Option<Vec<String>> = if tags.is_some() {
|
||||||
|
Some(tags.unwrap().split(",").map(str::to_string).collect())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let task = tasks.get_task(id)?;
|
||||||
|
|
||||||
|
if title.is_some() {
|
||||||
|
info(task_msg("renaming task", &task, id))
|
||||||
|
};
|
||||||
|
|
||||||
|
task.modify(title, notes, tags, when, deadline, reminder);
|
||||||
|
|
||||||
|
success(task_msg("modified", &task, id));
|
||||||
Ok(tasks)
|
Ok(tasks)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,11 +176,17 @@ pub fn execute(tasks: &mut Tasks, arguments: TasksArgs) -> Result<&mut Tasks, Ta
|
|||||||
Commands::Show(ShowTask { id }) => {
|
Commands::Show(ShowTask { id }) => {
|
||||||
if id.is_none() {
|
if id.is_none() {
|
||||||
if tasks.is_empty() {
|
if tasks.is_empty() {
|
||||||
info("no tasks found")
|
info(String::from("no tasks found"))
|
||||||
} else {
|
} else {
|
||||||
// Create the table for printing
|
// Create the table for printing
|
||||||
let mut table = Table::new();
|
let mut table = Table::new();
|
||||||
table.set_titles(row!["ID".magenta().bold(), "Status".magenta().bold(), "When".magenta().bold(), "Title".magenta().bold()]);
|
table.set_titles(row![
|
||||||
|
"ID".magenta().bold(),
|
||||||
|
"Status".magenta().bold(),
|
||||||
|
"Title".magenta().bold(),
|
||||||
|
"When".magenta().bold(),
|
||||||
|
"Deadline".magenta().bold(),
|
||||||
|
]);
|
||||||
table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
|
table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
|
||||||
|
|
||||||
// Iterate through each task
|
// Iterate through each task
|
||||||
@ -152,7 +206,10 @@ pub fn execute(tasks: &mut Tasks, arguments: TasksArgs) -> Result<&mut Tasks, Ta
|
|||||||
|
|
||||||
// Generate and print the table
|
// Generate and print the table
|
||||||
let mut table = Table::new();
|
let mut table = Table::new();
|
||||||
table.set_titles(row!["ID".magenta().bold(), "Status".magenta().bold(), "When".magenta().bold(), "Title".magenta().bold()]);
|
table.set_titles(row![
|
||||||
|
"Item".magenta().bold(),
|
||||||
|
"Value".magenta().bold(),
|
||||||
|
]);
|
||||||
table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
|
table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
|
||||||
table.add_row(calc_row(&task, id));
|
table.add_row(calc_row(&task, id));
|
||||||
println!("{}", table)
|
println!("{}", table)
|
||||||
@ -161,6 +218,6 @@ pub fn execute(tasks: &mut Tasks, arguments: TasksArgs) -> Result<&mut Tasks, Ta
|
|||||||
Ok(tasks)
|
Ok(tasks)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => todo!()
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
src/data.rs
11
src/data.rs
@ -1,12 +1,11 @@
|
|||||||
|
use dirs::home_dir;
|
||||||
|
use serde_json;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use dirs::home_dir;
|
|
||||||
use serde_json;
|
|
||||||
|
|
||||||
use crate::tasks::Tasks;
|
use crate::tasks::Tasks;
|
||||||
|
|
||||||
|
|
||||||
const TASKS_FILE_PATH: &str = "/.local/share/tasks";
|
const TASKS_FILE_PATH: &str = "/.local/share/tasks";
|
||||||
|
|
||||||
pub fn save_tasks<P: AsRef<Path>>(path: P, tasks: &Tasks) -> Result<(), Box<dyn Error>> {
|
pub fn save_tasks<P: AsRef<Path>>(path: P, tasks: &Tasks) -> Result<(), Box<dyn Error>> {
|
||||||
@ -30,5 +29,9 @@ pub fn load_tasks<P: AsRef<Path>>(path: P) -> Result<Tasks, Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn tasks_file_path() -> String {
|
pub fn tasks_file_path() -> String {
|
||||||
format!("{}{}", home_dir().unwrap().to_str().unwrap(), TASKS_FILE_PATH)
|
format!(
|
||||||
|
"{}{}",
|
||||||
|
home_dir().unwrap().to_str().unwrap(),
|
||||||
|
TASKS_FILE_PATH
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
mod tasks;
|
|
||||||
mod args;
|
mod args;
|
||||||
mod data;
|
|
||||||
mod cli;
|
mod cli;
|
||||||
|
mod data;
|
||||||
|
mod tasks;
|
||||||
|
|
||||||
use crate::tasks::Tasks;
|
|
||||||
use crate::args::TasksArgs;
|
use crate::args::TasksArgs;
|
||||||
use std::path::Path;
|
use crate::tasks::Tasks;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use colored::*;
|
use colored::*;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Generate the file path for tasks
|
// Generate the file path for tasks
|
||||||
|
101
src/tasks.rs
101
src/tasks.rs
@ -1,7 +1,6 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use colored::*;
|
use colored::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TasksError(String);
|
pub struct TasksError(String);
|
||||||
@ -16,11 +15,10 @@ pub enum Status {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct Task {
|
pub struct Task {
|
||||||
pub title: String, // The required title of the task
|
pub title: String, // The required title of the task
|
||||||
pub status: Status, // Current status of the task
|
pub status: Status, // Current status of the task
|
||||||
pub notes: Option<String>, // Any notes to explain the task
|
pub notes: Option<String>, // Any notes to explain the task
|
||||||
pub tags: Option<Vec<String>>, // Tasks can be tagged for organisation
|
pub tags: Option<Vec<String>>, // Tasks can be tagged for organisation
|
||||||
pub subtasks: Option<Vec<Task>>, // Tasks can be hierarchically split into subtasks
|
|
||||||
pub when: Option<NaiveDateTime>, // The date you want to do the task
|
pub when: Option<NaiveDateTime>, // The date you want to do the task
|
||||||
pub deadline: Option<NaiveDateTime>, // The latest date the task should be done
|
pub deadline: Option<NaiveDateTime>, // The latest date the task should be done
|
||||||
pub reminder: Option<NaiveDateTime>, // The datetime a reminder will alert you
|
pub reminder: Option<NaiveDateTime>, // The datetime a reminder will alert you
|
||||||
@ -32,13 +30,64 @@ pub struct Tasks {
|
|||||||
pub tasks: Option<Vec<Task>>, // All the tasks in one vector
|
pub tasks: Option<Vec<Task>>, // All the tasks in one vector
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Task {
|
fn task_not_found(id: usize) -> TasksError {
|
||||||
pub fn new(title: String, notes: Option<String>, tags: Option<Vec<String>>,
|
TasksError(format!("couldn't find task with id {}", id))
|
||||||
when: Option<NaiveDateTime>, deadline: Option<NaiveDateTime>,
|
}
|
||||||
reminder: Option<NaiveDateTime>) -> Self {
|
|
||||||
let status = if when.is_some() { Status::Pending } else { Status::Inbox };
|
|
||||||
|
|
||||||
Self { title, status, notes, tags, subtasks: None, when, deadline, reminder, }
|
fn no_tasks_available() -> TasksError {
|
||||||
|
TasksError(String::from("no tasks available"))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Task {
|
||||||
|
pub fn new(
|
||||||
|
title: String,
|
||||||
|
notes: Option<String>,
|
||||||
|
tags: Option<Vec<String>>,
|
||||||
|
when: Option<NaiveDateTime>,
|
||||||
|
deadline: Option<NaiveDateTime>,
|
||||||
|
reminder: Option<NaiveDateTime>,
|
||||||
|
) -> Self {
|
||||||
|
let status = if when.is_some() {
|
||||||
|
Status::Pending
|
||||||
|
} else {
|
||||||
|
Status::Inbox
|
||||||
|
};
|
||||||
|
|
||||||
|
Self {
|
||||||
|
title,
|
||||||
|
status,
|
||||||
|
notes,
|
||||||
|
tags,
|
||||||
|
when,
|
||||||
|
deadline,
|
||||||
|
reminder,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn modify(&mut self, title: Option<String>, notes: Option<String>, tags: Option<Vec<String>>, when: Option<NaiveDateTime>, deadline: Option<NaiveDateTime>, reminder: Option<NaiveDateTime>) {
|
||||||
|
if title.is_some() {
|
||||||
|
self.title = title.unwrap();
|
||||||
|
};
|
||||||
|
|
||||||
|
if notes.is_some() {
|
||||||
|
self.notes = Some(notes.unwrap());
|
||||||
|
};
|
||||||
|
|
||||||
|
if tags.is_some() {
|
||||||
|
self.tags = Some(tags.unwrap());
|
||||||
|
};
|
||||||
|
|
||||||
|
if when.is_some() {
|
||||||
|
self.when = Some(when.unwrap());
|
||||||
|
};
|
||||||
|
|
||||||
|
if deadline.is_some() {
|
||||||
|
self.deadline = Some(deadline.unwrap());
|
||||||
|
};
|
||||||
|
|
||||||
|
if reminder.is_some() {
|
||||||
|
self.reminder = Some(reminder.unwrap());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(&mut self) {
|
pub fn start(&mut self) {
|
||||||
@ -62,16 +111,16 @@ impl Tasks {
|
|||||||
pub fn new(tasks_path: &str) -> Self {
|
pub fn new(tasks_path: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
path: String::from(tasks_path),
|
path: String::from(tasks_path),
|
||||||
tasks: None
|
tasks: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn task_not_found(&self, id: usize) -> TasksError {
|
pub fn task_exists(&self, id: usize) -> bool {
|
||||||
TasksError(format!("couldn't find task with id {}", id))
|
if id >= self.len() {
|
||||||
}
|
false
|
||||||
|
} else {
|
||||||
fn task_exists(&self, id: usize) -> bool{
|
true
|
||||||
if id >= self.len() { false } else { true }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
@ -84,13 +133,12 @@ impl Tasks {
|
|||||||
|
|
||||||
pub fn get_task(&mut self, id: usize) -> Result<&mut Task, TasksError> {
|
pub fn get_task(&mut self, id: usize) -> Result<&mut Task, TasksError> {
|
||||||
if self.is_empty() {
|
if self.is_empty() {
|
||||||
Err(TasksError(format!("no tasks available")))
|
Err(no_tasks_available())
|
||||||
} else {
|
} else {
|
||||||
if self.task_exists(id) {
|
if self.task_exists(id) {
|
||||||
let task = &mut self.tasks.as_mut().unwrap()[id];
|
Ok(&mut self.tasks.as_mut().unwrap()[id])
|
||||||
Ok(task)
|
|
||||||
} else {
|
} else {
|
||||||
Err(TasksError(format!("couldn't find task with id {}", id)))
|
Err(task_not_found(id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,7 +156,7 @@ impl Tasks {
|
|||||||
self.tasks.as_mut().unwrap().remove(id);
|
self.tasks.as_mut().unwrap().remove(id);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(self.task_not_found(id))
|
Err(task_not_found(id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +170,7 @@ impl Tasks {
|
|||||||
|
|
||||||
pub fn clear(&mut self) -> Result<(), TasksError> {
|
pub fn clear(&mut self) -> Result<(), TasksError> {
|
||||||
if self.is_empty() {
|
if self.is_empty() {
|
||||||
Err(TasksError(String::from("no tasks available")))
|
Err(no_tasks_available())
|
||||||
} else {
|
} else {
|
||||||
self.tasks = None;
|
self.tasks = None;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -135,9 +183,8 @@ impl Status {
|
|||||||
match self {
|
match self {
|
||||||
Status::Inbox => "📮 Inbox".blue(),
|
Status::Inbox => "📮 Inbox".blue(),
|
||||||
Status::Pending => "📅 Pending".yellow(),
|
Status::Pending => "📅 Pending".yellow(),
|
||||||
Status::Active => "✍️ Active".red(),
|
Status::Active => "🕑 Active".red(),
|
||||||
Status::Complete => "📗 Complete".green(),
|
Status::Complete => "📗 Complete".green(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user