use std::path::{Path, PathBuf}; use crate::transaction::{Category, Transaction}; #[derive(Debug)] pub struct Store { root: PathBuf, transactions: Vec, new_transactions: Vec, } impl Store { //TODO Result pub fn open(root: PathBuf) -> Option { Some(Self { transactions: Self::open_dir(&root)?, new_transactions: Vec::new(), root, }) } //TODO check if hash matches //TODO Result //TODO overkill? maybe we can use subfolders later on fn open_dir(dir: &Path) -> Option> { let mut res = Vec::new(); for entry in std::fs::read_dir(dir).ok()? { let entry = entry.ok()?; if entry.file_type().ok()?.is_dir() { let mut transactions = Self::open_dir(&entry.path())?; res.append(&mut transactions); } else { res.push(Transaction::open(&entry.path())?); } } Some(res) } pub fn push(&mut self, transaction: Transaction) { self.new_transactions.push(transaction); } pub fn write(&self) -> std::io::Result<()> { for transaction in &self.new_transactions { let mut path = self.root.clone(); path.push(format!("{}", transaction.id())); transaction.write(&path)?; } Ok(()) } pub fn transactions(&self) -> Vec<&Transaction> { self.transactions.iter().collect() } pub fn categories(&self) -> Vec { let mut categories: Vec<_> = self .transactions .iter() .map(|t| t.category.clone()) .collect(); categories.sort(); categories.dedup(); categories } }