implement generic report generation
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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!(
|
||||
|
||||
Reference in New Issue
Block a user