summaryrefslogtreecommitdiffstats
path: root/cli/src/main.rs
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-07-31 20:23:01 +0200
committerGustav Sörnäs <gustav@sornas.net>2021-07-31 20:23:01 +0200
commit0c3510f690760db93b540f46ad4716e8614ba775 (patch)
tree5a91214c80e73c72e2b060ae08a073ce4428187b /cli/src/main.rs
parent10d6b82be501f219eb35b1cd94e1f0d461e9e165 (diff)
downloadmoney-0c3510f690760db93b540f46ad4716e8614ba775.tar.gz
sort inner
Diffstat (limited to 'cli/src/main.rs')
-rw-r--r--cli/src/main.rs56
1 files changed, 47 insertions, 9 deletions
diff --git a/cli/src/main.rs b/cli/src/main.rs
index c7b300b..22f0da2 100644
--- a/cli/src/main.rs
+++ b/cli/src/main.rs
@@ -27,8 +27,7 @@ enum Command {
#[structopt(long)]
account: String,
- // #[structopt(long = "category", multiple = true, number_of_values = 1)]
- // category: Vec<String>,
+ //TODO multiple
#[structopt(long)]
category: String,
@@ -44,9 +43,8 @@ enum Command {
},
#[structopt(setting = AppSettings::AllowLeadingHyphen)]
Show {
- //TODO multiple sorts (sort iequals with later sorts)
- #[structopt(long)]
- sort: Option<SortTarget>,
+ #[structopt(long, multiple = true, number_of_values = 1)]
+ sort: Vec<SortTarget>,
filters: Vec<String>,
},
@@ -140,11 +138,51 @@ fn main() {
search = search.parse(filters.join(" "));
}
let mut transactions = search.get();
- transactions.sort_by(|t1, t2| match sort {
- Some(SortTarget::Amount) => t1.amount.cmp(&t2.amount),
- Some(SortTarget::Date) | None => t1.date.cmp(&t2.date),
- });
+ if sort.is_empty() {
+ transactions.sort_by_key(|t| t.date);
+ } else {
+ match &sort[0] {
+ SortTarget::Amount => transactions.sort_by_key(|t| t.amount),
+ SortTarget::Date => transactions.sort_by_key(|t| t.date),
+ }
+ for i in 1..sort.len() {
+ //TODO macro? dynamic dispatch? trait objects?
+ match (&sort[i-1], &sort[i]) {
+ (SortTarget::Amount, SortTarget::Date)
+ => inner_sort_by_key(&mut transactions, |t| t.amount, |t| t.date),
+ (SortTarget::Date, SortTarget::Amount)
+ => inner_sort_by_key(&mut transactions, |t| t.date, |t| t.amount),
+ _ => panic!(),
+ }
+ }
+ }
println!("{}", Table::new(transactions).with(Style::psql()));
}
}
}
+
+fn inner_sort_by_key<F, G, K, L, T>(v: &mut [T], mut outer_key: F, mut inner_key: G)
+where F: FnMut(&T) -> K,
+ G: FnMut(&T) -> L,
+ K: Ord,
+ L: Ord,
+{
+ // Early out
+ if v.len() < 2 {
+ return;
+ }
+
+ let mut lower = 0; // Lower bound of current equal range
+ let mut last_k = outer_key(&v[0]); // Current key
+ for i in 0..v.len() {
+ let i_k = outer_key(&v[i]);
+ if i_k != last_k {
+ let upper = i;
+ if upper - lower > 1 {
+ v[lower..upper].sort_by_key(&mut inner_key);
+ }
+ lower = i;
+ last_k = i_k;
+ }
+ }
+}