diff options
| -rw-r--r-- | Cargo.lock | 2 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | budget/src/lib.rs | 31 | ||||
| -rw-r--r-- | budget/tests/budget.rs | 29 | ||||
| -rw-r--r-- | budget/tests/test.toml | 6 | ||||
| -rw-r--r-- | src/main.rs | 17 | 
6 files changed, 46 insertions, 41 deletions
| @@ -82,7 +82,7 @@ dependencies = [  [[package]]  name = "finbudg" -version = "0.1.0" +version = "0.1.2"  dependencies = [   "budget",   "chrono", @@ -1,6 +1,6 @@  [package]  name = "finbudg" -version = "0.1.1" +version = "0.1.2"  edition = "2018"  description = "Quick cli tool to calculate your expenses and balance for a set period of time."  license = "MIT" diff --git a/budget/src/lib.rs b/budget/src/lib.rs index e8bb8f3..7d7c390 100644 --- a/budget/src/lib.rs +++ b/budget/src/lib.rs @@ -51,6 +51,7 @@ pub struct Calculated {      pub balance: f64,      pub days_left: f64,      pub days_left_essential: f64, +    pub last_day: NaiveDate,  }  #[derive(PartialEq, Eq, Debug)] @@ -96,7 +97,11 @@ pub fn parse_account(path: &str) -> Result<Account, ParseError> {      }  } -pub fn calculate(account: &Account) -> Calculated { +pub fn calculate(account: &Account) -> Option<Calculated> { +    if account.days.len() < 1 { +        return None; +    } +      let mut calculated = Calculated {          all_day_average: 0.0,          essential_day_average: 0.0, @@ -107,12 +112,13 @@ pub fn calculate(account: &Account) -> Calculated {          balance: 0.0,          days_left: 0.0,          days_left_essential: 0.0, +        last_day: account.days.last().unwrap().date,      }; -    let mut days_calculated = 0; -      for day in account.days.iter() { -        days_calculated += 1; +        if day.date > calculated.last_day { +            calculated.last_day = day.date; +        }          for expense in day.expenses.iter() {              calculated.total += expense.price; @@ -135,15 +141,18 @@ pub fn calculate(account: &Account) -> Calculated {          }      } -    calculated.all_day_average = calculated.total / days_calculated as f64; +    let days_elapsed =  +        (calculated.last_day - account.start_date).num_days() + 1; + +    calculated.all_day_average = calculated.total / days_elapsed as f64;      calculated.essential_day_average =  -        calculated.essential_subtotal / days_calculated as f64; +        calculated.essential_subtotal / days_elapsed as f64;      for (category, subtotal) in calculated.categories_subtotal.iter() {          calculated.categories_day_average              .insert(                  category.clone(), -                subtotal / days_calculated as f64, +                subtotal / days_elapsed as f64,              );      } @@ -153,11 +162,5 @@ pub fn calculate(account: &Account) -> Calculated {      calculated.days_left_essential =           calculated.balance / calculated.essential_day_average; -    calculated -} - -pub fn get_calculated(path: &str) -> Result<Calculated, ParseError> { -    let account = parse_account(path)?; - -    Ok(calculate(&account)) +    Some(calculated)  } diff --git a/budget/tests/budget.rs b/budget/tests/budget.rs index 1cc02e7..feae240 100644 --- a/budget/tests/budget.rs +++ b/budget/tests/budget.rs @@ -1,6 +1,6 @@  use std::collections::HashMap; -use chrono::prelude::*; +use chrono::NaiveDate;  use budget::*; @@ -62,6 +62,10 @@ fn can_parse_account() -> Result<(), ParseError>{                  ],              },              Day { +                date: NaiveDate::from_ymd(2020, 10, 4), +                expenses: Vec::<Expense>::new(), +            }, +            Day {                  date: NaiveDate::from_ymd(2020, 10, 2),                  expenses: vec![                      Expense { @@ -82,10 +86,6 @@ fn can_parse_account() -> Result<(), ParseError>{                      },                  ],              }, -            Day { -                date: NaiveDate::from_ymd(2020, 10, 3), -                expenses: Vec::<Expense>::new(), -            },          ],      }; @@ -99,32 +99,33 @@ fn can_parse_account() -> Result<(), ParseError>{  #[test]  fn can_calculate() -> Result<(), ParseError> {      let mut should_be = Calculated { -        all_day_average: 7.57, -        essential_day_average: 6.3, +        all_day_average: 5.6775, +        essential_day_average: 4.725,          categories_day_average: HashMap::<String, f64>::new(),          essential_subtotal: 18.9,          categories_subtotal: HashMap::<String, f64>::new(),          total: 22.71,          balance: 397.29, -        days_left: 52.48216644649934, -        days_left_essential: 63.06190476190476, +        days_left: 69.9762219286658, +        days_left_essential: 84.08253968253969, +        last_day: NaiveDate::from_ymd(2020, 10, 04),      };      should_be.categories_day_average.insert(          "supplies".to_string(), -        1.27, +        0.9525,      );      should_be.categories_day_average.insert(          "products".to_string(), -        2.3333333333333335, +        1.75,      );      should_be.categories_day_average.insert(          "transport".to_string(), -        2.3000000000000003, +        1.725,      );      should_be.categories_day_average.insert(          "utilities".to_string(), -        1.6666666666666667, +        1.25,      );      should_be.categories_subtotal.insert( @@ -145,7 +146,7 @@ fn can_calculate() -> Result<(), ParseError> {      );      let account = budget::parse_account("tests/test.toml")?; -    let actually_is = budget::calculate(&account); +    let actually_is = budget::calculate(&account).unwrap();      assert_eq!(actually_is, should_be); diff --git a/budget/tests/test.toml b/budget/tests/test.toml index 1bb1ce7..a29467e 100644 --- a/budget/tests/test.toml +++ b/budget/tests/test.toml @@ -39,6 +39,9 @@ date = 2020-10-01    shared = 2  [[days]] +date = 2020-10-04 + +[[days]]  date = 2020-10-02    [[days.expenses]] @@ -52,6 +55,3 @@ date = 2020-10-02    price = 6.9    category = "transport" -[[days]] -date = 2020-10-03 - diff --git a/src/main.rs b/src/main.rs index 04d5277..5c64959 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,7 +33,7 @@ fn main() {              ::std::process::exit(1);          }      }; -    let calculated = budget::calculate(&account); +    let maybe_calculated = budget::calculate(&account);      if no_color && !force_color {          colored::control::set_override(false); @@ -41,7 +41,7 @@ fn main() {          colored::control::set_override(true);      } -    output(account, calculated); +    output(account, maybe_calculated);  }  fn get_cli_matches() -> ArgMatches<'static> { @@ -68,7 +68,7 @@ fn get_cli_matches() -> ArgMatches<'static> {          .get_matches()  } -fn output(account: Account, calculated: Calculated) { +fn output(account: Account, maybe_calculated: Option<Calculated>) {      println!(          "{}",          format!( @@ -78,22 +78,23 @@ fn output(account: Account, calculated: Calculated) {          ).cyan(),      ); -    let last_day = match account.days.last() { -        Some(day) => day, +    let calculated = match maybe_calculated { +        Some(data) => data,          None => { -            println!("{}", "Your expenses are empty...".italic()); +            println!(); +            println!("{}", "You have no expenses...".italic());              ::std::process::exit(0);          }      }; -    let days_until_end = account.end_date - last_day.date; +    let days_until_end = account.end_date - calculated.last_day;      println!(          "{}",           format!(              "Last day on entry: {}", -            last_day.date.format("%Y-%m-%d"), +            calculated.last_day.format("%Y-%m-%d"),          ).cyan(),      ); | 
