Compare commits
1 commit
7d9284bf91
...
6d610dc440
| Author | SHA1 | Date | |
|---|---|---|---|
| 6d610dc440 |
3 changed files with 50 additions and 6 deletions
|
|
@ -23,7 +23,11 @@ struct Args {
|
|||
#[derive(clap::Subcommand, Debug)]
|
||||
enum Commands {
|
||||
/// List issues.
|
||||
List,
|
||||
List {
|
||||
/// Filter string, describes issues to include in the list.
|
||||
#[arg(default_value_t = String::from("state=New,Backlog,Blocked,InProgress"))]
|
||||
filter: String,
|
||||
},
|
||||
|
||||
/// Create a new issue.
|
||||
New { description: Option<String> },
|
||||
|
|
@ -43,11 +47,14 @@ enum Commands {
|
|||
|
||||
fn handle_command(args: &Args, issues_dir: &std::path::Path) -> anyhow::Result<()> {
|
||||
match &args.command {
|
||||
Commands::List => {
|
||||
Commands::List { filter } => {
|
||||
let issues =
|
||||
entomologist::issues::Issues::new_from_dir(std::path::Path::new(issues_dir))?;
|
||||
let filter = entomologist::parse_filter(filter)?;
|
||||
for (uuid, issue) in issues.issues.iter() {
|
||||
println!("{} {} ({:?})", uuid, issue.title(), issue.state);
|
||||
if filter.include_states.contains(&issue.state) {
|
||||
println!("{} {} ({:?})", uuid, issue.title(), issue.state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::str::FromStr;
|
|||
#[cfg(feature = "log")]
|
||||
use log::debug;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, serde::Deserialize)]
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, serde::Deserialize)]
|
||||
/// These are the states an issue can be in.
|
||||
pub enum State {
|
||||
New,
|
||||
|
|
@ -35,6 +35,8 @@ pub enum IssueError {
|
|||
StdIoError(#[from] std::io::Error),
|
||||
#[error("Failed to parse issue")]
|
||||
IssueParseError,
|
||||
#[error("Failed to parse state")]
|
||||
StateParseError,
|
||||
#[error("Failed to run git")]
|
||||
GitError(#[from] crate::git::GitError),
|
||||
#[error("Failed to run editor")]
|
||||
|
|
@ -58,7 +60,7 @@ impl FromStr for State {
|
|||
} else if s == "wontdo" {
|
||||
Ok(State::WontDo)
|
||||
} else {
|
||||
Err(IssueError::IssueParseError)
|
||||
Err(IssueError::StateParseError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -72,7 +74,6 @@ impl fmt::Display for State {
|
|||
State::InProgress => "inprogress",
|
||||
State::Done => "done",
|
||||
State::WontDo => "wontdo",
|
||||
|
||||
};
|
||||
write!(f, "{fmt_str}")
|
||||
}
|
||||
|
|
|
|||
36
src/lib.rs
36
src/lib.rs
|
|
@ -1,3 +1,39 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
pub mod git;
|
||||
pub mod issue;
|
||||
pub mod issues;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ParseFilterError {
|
||||
#[error("Failed to parse filter")]
|
||||
ParseError,
|
||||
#[error(transparent)]
|
||||
IssueParseError(#[from] crate::issue::IssueError),
|
||||
}
|
||||
|
||||
// FIXME: It's easy to imagine a full dsl for filtering issues, for now
|
||||
// i'm starting with obvious easy things. Chumsky looks appealing but
|
||||
// more research is needed.
|
||||
#[derive(Debug)]
|
||||
pub struct Filter {
|
||||
pub include_states: std::collections::HashSet<crate::issue::State>,
|
||||
}
|
||||
|
||||
// Parses a filter description matching "state=STATE[,STATE*]"
|
||||
pub fn parse_filter(filter_str: &str) -> Result<Filter, ParseFilterError> {
|
||||
let tokens: Vec<&str> = filter_str.split("=").collect();
|
||||
if tokens.len() != 2 {
|
||||
return Err(ParseFilterError::ParseError);
|
||||
}
|
||||
if tokens[0] != "state" {
|
||||
return Err(ParseFilterError::ParseError);
|
||||
}
|
||||
|
||||
let mut include_states = std::collections::HashSet::<crate::issue::State>::new();
|
||||
for s in tokens[1].split(",") {
|
||||
include_states.insert(crate::issue::State::from_str(s)?);
|
||||
}
|
||||
|
||||
Ok(Filter { include_states })
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue