use chrono::{NaiveDate, Utc}; use chrono::Datelike; use regex::Regex; #[derive(Debug)] pub struct DateRange { start_year : i32, start_month : u32, end_year : i32, end_month : u32, last : bool, } impl DateRange { pub fn new(start : chrono::NaiveDate, end : chrono::NaiveDate) -> DateRange { DateRange { start_year : start.year(), start_month : start.month(), end_year : end.year(), end_month : end.month(), last : false, } } } impl Iterator for DateRange { type Item = chrono::NaiveDate; fn next(&mut self) -> Option { if self.last { return None } if self.start_year == self.end_year && self.start_month == self.end_month { self.last = true; } let mut tmp = self.start_year.to_string(); if self.start_month < 10 { tmp.push_str("-0"); } else { tmp.push_str("-"); } tmp.push_str(&self.start_month.to_string()); tmp.push_str("-01"); if self.start_month < 12 { self.start_month = self.start_month + 1; } else { self.start_month = 1; self.start_year = self.start_year + 1; } return Some(chrono::NaiveDate::parse_from_str(&tmp, "%Y-%m-%d").unwrap()) } } /* This files contains the code to handle the /transactions requests */ struct TransactionFilter { sender_name_filter : Vec, reference_filter : Vec } /* * files syntax: . seperates different search critereas * a search crietera is a key value pair, with key as fiter type, e.g. * sender name of transation. The value is what is should be and can be a regex * key value pair is split by - */ pub fn apply_transaction_filter(filter : String, transactions : Vec) -> Vec { let mut tmp = transactions.clone(); // special case if for general search if !filter.to_string().contains(";") { println!("in special case"); let re = Regex::new(&filter).unwrap(); tmp = transactions.into_iter().filter(|transaction| re.is_match(&transaction.sender_name) || re.is_match(&transaction.reference) ).collect(); return tmp; } // parse filter string and construct TransactionFilter struct let mut sender_name_vec = Vec::new(); let mut reference_vec = Vec::new(); for entry in filter.to_string().split(";") { let v : Vec<_> = entry.split("-").collect(); println!("{:?}", v); if v.len() > 1 { if v[0] == "sender" { println!("Filter for sender_name"); sender_name_vec.push(v[1].to_string()); } else if v[0] == "reference" { println!("filter for reference"); reference_vec.push(v[1].to_string()); } } } tmp = transactions.clone().into_iter().filter(|transaction| { let mut sender_match = false; let mut reference_match = false; for sender in &sender_name_vec { let re_sender = Regex::new(&sender).unwrap(); if re_sender.is_match(&transaction.sender_name) { sender_match = true; } } for reference in &reference_vec { let re = Regex::new(&reference).unwrap(); if re.is_match(&transaction.reference) { reference_match = true; } } sender_match || reference_match }).collect(); tmp }