more list filtering options

This commit is contained in:
aaron-jack-manning 2022-09-03 11:24:13 +10:00
parent 69507689b3
commit 310aa84f50
2 changed files with 29 additions and 5 deletions

View File

@ -118,6 +118,12 @@ pub struct ListOptions {
/// Tags to include.
#[clap(short, long)]
pub tag : Vec<String>,
/// Tags to exclude.
#[clap(short, long)]
pub exclude_tag : Vec<String>,
/// Priority levels to include.
#[clap(short, long, value_enum)]
pub priority : Vec<tasks::Priority>,
/// Only include tasks due before a certain date (inclusive).
#[clap(long)]
pub due_before : Option<chrono::NaiveDate>,
@ -148,15 +154,14 @@ pub enum Order {
Desc,
}
#[derive(Default, Hash, Clone, Debug, PartialEq, Eq, clap::ValueEnum, serde::Serialize, serde::Deserialize)]
#[derive(Hash, Clone, Debug, PartialEq, Eq, clap::ValueEnum, serde::Serialize, serde::Deserialize)]
pub enum Column {
#[default]
Due,
Priority,
Created,
Tracked,
Tags,
Status,
Tracked,
}
#[derive(Default, Clone, Debug, PartialEq, Eq, clap::ValueEnum, serde::Serialize, serde::Deserialize)]

View File

@ -21,7 +21,7 @@ pub struct Task {
pub data : InternalTask,
}
#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum, serde::Serialize, serde::Deserialize)]
#[derive(Default, Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum, serde::Serialize, serde::Deserialize)]
pub enum Priority {
#[default]
Low,
@ -382,7 +382,6 @@ pub fn list(mut options : super::ListOptions, vault_folder : &path::Path, state
}
}));
}
if let Some(date) = options.due_after {
tasks = Box::new(tasks.filter(move |t| {
match compare_due_dates(&t.data.due.map(|d| d.date()), &Some(date)) {
@ -407,6 +406,26 @@ pub fn list(mut options : super::ListOptions, vault_folder : &path::Path, state
}));
}
if !options.exclude_tag.is_empty() {
let specified_tags : HashSet<_> = options.exclude_tag.iter().collect();
tasks = Box::new(tasks.filter(move |t| {
let task_tags : HashSet<_> = t.data.tags.iter().collect();
// If the task contains a tag which was supposed to be excluded, it should be filtered
// out
!specified_tags.intersection(&task_tags).next().is_some()
}));
}
if !options.priority.is_empty() {
let specified_priority_levels : HashSet<_> = options.priority.iter().collect();
tasks = Box::new(tasks.filter(move |t| {
specified_priority_levels.contains(&t.data.priority)
}));
}
if options.no_dependencies {
tasks = Box::new(tasks.filter(move |t| {
t.data.dependencies.is_empty()