summaryrefslogtreecommitdiffstats
path: root/cli/src
diff options
context:
space:
mode:
Diffstat (limited to 'cli/src')
-rw-r--r--cli/src/main.rs17
-rw-r--r--cli/src/search.rs62
-rw-r--r--cli/src/store.rs6
3 files changed, 81 insertions, 4 deletions
diff --git a/cli/src/main.rs b/cli/src/main.rs
index 5fd52c7..071e251 100644
--- a/cli/src/main.rs
+++ b/cli/src/main.rs
@@ -4,9 +4,14 @@ use std::path::PathBuf;
use std::str::FromStr;
use structopt::StructOpt;
+mod search;
mod store;
mod transaction;
+use search::{Constraint, Search};
+use store::Store;
+use transaction::{Transaction, TransactionKind};
+
//TODO relative ("yesterday", "-2d", etc)
fn parse_date(s: &str) -> Result<NaiveDate, String> {
NaiveDate::parse_from_str(s, "%Y-%m-%d").map_err(|e| e.to_string())
@@ -16,7 +21,7 @@ fn parse_date(s: &str) -> Result<NaiveDate, String> {
#[derive(StructOpt)]
enum Command {
Insert {
- kind: transaction::TransactionKind,
+ kind: TransactionKind,
#[structopt(long)]
account: String,
@@ -62,7 +67,13 @@ struct Mn {
}
fn main() {
- let mut store = store::Store::open(PathBuf::from("store")).unwrap();
+ let mut store = Store::open(PathBuf::from("store")).unwrap();
+
+ let search = Search::new(store.transactions().iter().collect());
+ println!("{:?}", search.get());
+ let search = search.subtract(Constraint::Category("a".to_string()));
+ println!("{:?}", search.get());
+
let args = Mn::from_args();
eprintln!("{:?}", args);
match args.command {
@@ -74,7 +85,7 @@ fn main() {
description,
date,
} => {
- let transaction = transaction::Transaction {
+ let transaction = Transaction {
kind,
to: account,
from: "Default".to_string(),
diff --git a/cli/src/search.rs b/cli/src/search.rs
new file mode 100644
index 0000000..d388a8b
--- /dev/null
+++ b/cli/src/search.rs
@@ -0,0 +1,62 @@
+use chrono::{naive::NaiveDate, Duration};
+
+use crate::transaction::{Category, Transaction};
+
+pub struct Search<'t> {
+ filtered: Vec<usize>,
+ transactions: Vec<&'t Transaction>,
+}
+
+pub enum DateFilter {
+ Absolute {
+ start: Option<NaiveDate>,
+ end: Option<NaiveDate>,
+ },
+ Relative {
+ start: Option<Duration>,
+ end: Option<Duration>,
+ }
+}
+
+pub enum Constraint {
+ Category(Category),
+ Date(DateFilter),
+}
+
+impl Constraint {
+ fn satisfies(&self, t: &Transaction) -> bool {
+ match self {
+ Constraint::Category(category) => category == &t.category,
+ Constraint::Date(_) => todo!(),
+ }
+ }
+}
+
+impl<'t> Search<'t> {
+ pub fn new(transactions: Vec<&'t Transaction>) -> Self {
+ Self {
+ filtered: std::iter::successors(Some(0_usize), |n| Some(n.checked_add(1).unwrap())).take(transactions.len()).collect(),
+ transactions,
+ }
+ }
+
+ pub fn get(&self) -> Vec<&'t Transaction> {
+ self
+ .filtered
+ .iter()
+ .map(|idx| self.transactions[*idx])
+ .collect()
+ }
+
+ pub fn subtract(self, constraint: Constraint) -> Self {
+ Self {
+ filtered: self
+ .filtered
+ .iter()
+ .copied()
+ .filter(|idx| !constraint.satisfies(self.transactions[*idx]))
+ .collect(),
+ transactions: self.transactions,
+ }
+ }
+}
diff --git a/cli/src/store.rs b/cli/src/store.rs
index 2bba9c8..4e0e36b 100644
--- a/cli/src/store.rs
+++ b/cli/src/store.rs
@@ -49,9 +49,13 @@ impl Store {
Ok(())
}
+ pub fn transactions(&self) -> &[Transaction] {
+ &self.transactions
+ }
+
pub fn categories(&self) -> Vec<Category> {
let mut categories: Vec<_> = self
- .transactions
+ .transactions()
.iter()
.map(|t| t.category.clone())
.collect();