implement generic report generation

This commit is contained in:
Dustin J. Mitchell
2020-12-26 04:07:36 +00:00
parent f264e74288
commit 00f548c713
7 changed files with 484 additions and 50 deletions

View File

@@ -22,7 +22,7 @@ pub(crate) use args::TaskId;
pub(crate) use command::Command;
pub(crate) use filter::{Condition, Filter, Universe};
pub(crate) use modification::{DescriptionMod, Modification};
pub(crate) use report::Report;
pub(crate) use report::{Column, Property, Report, Sort, SortBy};
pub(crate) use subcommand::Subcommand;
use crate::usage::Usage;

View File

@@ -1,33 +1,68 @@
use super::{ArgList, Filter};
use nom::IResult;
use super::Filter;
/// A report specifies a filter as well as a sort order and information about which
/// task attributes to display
#[derive(Debug, PartialEq, Default)]
#[derive(Clone, Debug, PartialEq, Default)]
pub(crate) struct Report {
/// Columns to display in this report
pub columns: Vec<Column>,
/// Sort order for this report
pub sort: Vec<Sort>,
/// Filter selecting tasks for this report
pub filter: Filter,
}
impl Report {
pub(super) fn parse(input: ArgList) -> IResult<ArgList, Report> {
let (input, filter) = Filter::parse(input)?;
Ok((input, Report { filter }))
}
/// A column to display in a report
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct Column {
/// The label for this column
pub label: String,
/// The property to display
pub property: Property,
}
#[cfg(test)]
mod test {
use super::*;
/// Task property to display in a report
#[derive(Clone, Debug, PartialEq)]
#[allow(dead_code)]
pub(crate) enum Property {
/// The task's ID, either working-set index or Uuid if no in the working set
Id,
#[test]
fn test_empty() {
let (input, report) = Report::parse(argv![]).unwrap();
assert_eq!(input.len(), 0);
assert_eq!(
report,
Report {
..Default::default()
}
);
}
/// The task's full UUID
Uuid,
/// Whether the task is active or not
Active,
/// The task's description
Description,
/// The task's tags
Tags,
}
/// A sorting criterion for a sort operation.
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct Sort {
/// True if the sort should be "ascending" (a -> z, 0 -> 9, etc.)
pub ascending: bool,
/// The property to sort on
pub sort_by: SortBy,
}
/// Task property to sort by
#[derive(Clone, Debug, PartialEq)]
#[allow(dead_code)]
pub(crate) enum SortBy {
/// The task's ID, either working-set index or a UUID prefix; working
/// set tasks sort before others.
Id,
/// The task's full UUID
Uuid,
/// The task's description
Description,
}

View File

@@ -1,5 +1,7 @@
use super::args::*;
use super::{ArgList, DescriptionMod, Filter, Modification, Report};
use super::{
ArgList, Column, DescriptionMod, Filter, Modification, Property, Report, Sort, SortBy,
};
use crate::usage;
use nom::{branch::alt, combinator::*, sequence::*, IResult};
use taskchampion::Status;
@@ -252,12 +254,45 @@ impl Modify {
struct List;
impl List {
// temporary
fn default_report() -> Report {
Report {
columns: vec![
Column {
label: "Id".to_owned(),
property: Property::Id,
},
Column {
label: "Description".to_owned(),
property: Property::Description,
},
Column {
label: "Active".to_owned(),
property: Property::Active,
},
Column {
label: "Tags".to_owned(),
property: Property::Tags,
},
],
sort: vec![Sort {
ascending: false,
sort_by: SortBy::Uuid,
}],
..Default::default()
}
}
fn parse(input: ArgList) -> IResult<ArgList, Subcommand> {
fn to_subcommand(input: (Report, &str)) -> Result<Subcommand, ()> {
Ok(Subcommand::List { report: input.0 })
fn to_subcommand(input: (Filter, &str)) -> Result<Subcommand, ()> {
let report = Report {
filter: input.0,
..List::default_report()
};
Ok(Subcommand::List { report })
}
map_res(
pair(Report::parse, arg_matching(literal("list"))),
pair(Filter::parse, arg_matching(literal("list"))),
to_subcommand,
)(input)
}
@@ -602,7 +637,7 @@ mod test {
fn test_list() {
let subcommand = Subcommand::List {
report: Report {
..Default::default()
..List::default_report()
},
};
assert_eq!(
@@ -619,6 +654,7 @@ mod test {
universe: Universe::for_ids(vec![12, 13]),
..Default::default()
},
..List::default_report()
},
};
assert_eq!(