Support CLI syntax for changing tags

This commit is contained in:
Dustin J. Mitchell
2020-12-21 19:40:07 +00:00
parent 28c5fb2268
commit 54e8484bc2
4 changed files with 97 additions and 35 deletions

View File

@@ -1,6 +1,7 @@
use super::args::{any, arg_matching};
use super::args::{any, arg_matching, minus_tag, plus_tag};
use super::ArgList;
use nom::{combinator::*, multi::fold_many0, IResult};
use nom::{branch::alt, combinator::*, multi::fold_many0, IResult};
use std::collections::HashSet;
use taskchampion::Status;
#[derive(Debug, PartialEq, Clone)]
@@ -34,13 +35,21 @@ pub struct Modification {
/// Set the status
pub status: Option<Status>,
/// Set the "active" status, that is, start (true) or stop (false) the task.
/// Set the "active" state, that is, start (true) or stop (false) the task.
pub active: Option<bool>,
/// Add tags
pub add_tags: HashSet<String>,
/// Remove tags
pub remove_tags: HashSet<String>,
}
/// A single argument that is part of a modification, used internally to this module
enum ModArg<'a> {
Description(&'a str),
PlusTag(&'a str),
MinusTag(&'a str),
}
impl Modification {
@@ -55,11 +64,22 @@ impl Modification {
acc.description = DescriptionMod::Set(description.to_string());
}
}
ModArg::PlusTag(tag) => {
acc.add_tags.insert(tag.to_owned());
}
ModArg::MinusTag(tag) => {
acc.remove_tags.insert(tag.to_owned());
}
}
acc
}
fold_many0(
Self::description,
alt((
Self::plus_tag,
Self::minus_tag,
// this must come last
Self::description,
)),
Modification {
..Default::default()
},
@@ -73,6 +93,20 @@ impl Modification {
}
map_res(arg_matching(any), to_modarg)(input)
}
fn plus_tag(input: ArgList) -> IResult<ArgList, ModArg> {
fn to_modarg(input: &str) -> Result<ModArg, ()> {
Ok(ModArg::PlusTag(input))
}
map_res(arg_matching(plus_tag), to_modarg)(input)
}
fn minus_tag(input: ArgList) -> IResult<ArgList, ModArg> {
fn to_modarg(input: &str) -> Result<ModArg, ()> {
Ok(ModArg::MinusTag(input))
}
map_res(arg_matching(minus_tag), to_modarg)(input)
}
}
#[cfg(test)]
@@ -104,6 +138,19 @@ mod test {
);
}
#[test]
fn test_add_tags() {
let (input, modification) = Modification::parse(argv!["+abc", "+def"]).unwrap();
assert_eq!(input.len(), 0);
assert_eq!(
modification,
Modification {
add_tags: set!["abc".to_owned(), "def".to_owned()],
..Default::default()
}
);
}
#[test]
fn test_multi_arg_description() {
let (input, modification) = Modification::parse(argv!["new", "desc", "fun"]).unwrap();
@@ -116,4 +163,20 @@ mod test {
}
);
}
#[test]
fn test_multi_arg_description_and_tags() {
let (input, modification) =
Modification::parse(argv!["new", "+next", "desc", "-daytime", "fun"]).unwrap();
assert_eq!(input.len(), 0);
assert_eq!(
modification,
Modification {
description: DescriptionMod::Set("new desc fun".to_owned()),
add_tags: set!["next".to_owned()],
remove_tags: set!["daytime".to_owned()],
..Default::default()
}
);
}
}