ent list FILTER: add filter "done-time=[START]..[END]"
This commit is contained in:
parent
bc2b1bd3c1
commit
a3077ca313
2 changed files with 47 additions and 0 deletions
|
|
@ -41,6 +41,13 @@ enum Commands {
|
||||||
/// if prefixed with "-". Example: "tag=bug,-docs" shows issues
|
/// if prefixed with "-". Example: "tag=bug,-docs" shows issues
|
||||||
/// that are tagged "bug" and not tagged "docs". Defaults to
|
/// that are tagged "bug" and not tagged "docs". Defaults to
|
||||||
/// including all tags and excluding none.
|
/// including all tags and excluding none.
|
||||||
|
///
|
||||||
|
/// "done-time": Time range of issue completion, in the form
|
||||||
|
/// "[START]..[END]". Includes issues that were marked Done
|
||||||
|
/// between START and END. START and END are both in RFC 3339
|
||||||
|
/// format, e.g. "YYYY-MM-DDTHH:MM:SS[+-]HH:MM". If START
|
||||||
|
/// is omitted, defaults to the beginning of time. If END is
|
||||||
|
/// omitted, defaults to the end of time.
|
||||||
filter: Vec<String>,
|
filter: Vec<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -138,6 +145,19 @@ fn handle_command(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(issue_done_time) = issue.done_time {
|
||||||
|
if let Some(start_done_time) = filter.start_done_time {
|
||||||
|
if start_done_time > issue_done_time {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(end_done_time) = filter.end_done_time {
|
||||||
|
if end_done_time < issue_done_time {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This issue passed all the filters, include it in list.
|
// This issue passed all the filters, include it in list.
|
||||||
uuids_by_state
|
uuids_by_state
|
||||||
.entry(issue.state.clone())
|
.entry(issue.state.clone())
|
||||||
|
|
|
||||||
27
src/lib.rs
27
src/lib.rs
|
|
@ -14,6 +14,8 @@ pub enum ParseFilterError {
|
||||||
ParseError,
|
ParseError,
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
IssueParseError(#[from] crate::issue::IssueError),
|
IssueParseError(#[from] crate::issue::IssueError),
|
||||||
|
#[error(transparent)]
|
||||||
|
ChronoParseError(#[from] chrono::format::ParseError),
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: It's easy to imagine a full dsl for filtering issues, for now
|
// FIXME: It's easy to imagine a full dsl for filtering issues, for now
|
||||||
|
|
@ -25,6 +27,8 @@ pub struct Filter<'a> {
|
||||||
pub include_assignees: std::collections::HashSet<&'a str>,
|
pub include_assignees: std::collections::HashSet<&'a str>,
|
||||||
pub include_tags: std::collections::HashSet<&'a str>,
|
pub include_tags: std::collections::HashSet<&'a str>,
|
||||||
pub exclude_tags: std::collections::HashSet<&'a str>,
|
pub exclude_tags: std::collections::HashSet<&'a str>,
|
||||||
|
pub start_done_time: Option<chrono::DateTime<chrono::Local>>,
|
||||||
|
pub end_done_time: Option<chrono::DateTime<chrono::Local>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Filter<'a> {
|
impl<'a> Filter<'a> {
|
||||||
|
|
@ -39,6 +43,8 @@ impl<'a> Filter<'a> {
|
||||||
include_assignees: std::collections::HashSet::<&'a str>::new(),
|
include_assignees: std::collections::HashSet::<&'a str>::new(),
|
||||||
include_tags: std::collections::HashSet::<&'a str>::new(),
|
include_tags: std::collections::HashSet::<&'a str>::new(),
|
||||||
exclude_tags: std::collections::HashSet::<&'a str>::new(),
|
exclude_tags: std::collections::HashSet::<&'a str>::new(),
|
||||||
|
start_done_time: None,
|
||||||
|
end_done_time: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,6 +85,27 @@ impl<'a> Filter<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"done-time" => {
|
||||||
|
self.start_done_time = None;
|
||||||
|
self.end_done_time = None;
|
||||||
|
let times: Vec<&str> = tokens[1].split("..").collect();
|
||||||
|
if times.len() > 2 {
|
||||||
|
return Err(ParseFilterError::ParseError);
|
||||||
|
}
|
||||||
|
if times[0].len() != 0 {
|
||||||
|
self.start_done_time = Some(
|
||||||
|
chrono::DateTime::parse_from_rfc3339(times[0])?
|
||||||
|
.with_timezone(&chrono::Local),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if times[1].len() != 0 {
|
||||||
|
self.end_done_time = Some(
|
||||||
|
chrono::DateTime::parse_from_rfc3339(times[1])?
|
||||||
|
.with_timezone(&chrono::Local),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
println!("unknown filter string '{}'", filter_str);
|
println!("unknown filter string '{}'", filter_str);
|
||||||
return Err(ParseFilterError::ParseError);
|
return Err(ParseFilterError::ParseError);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue