|
| 1 | +#[derive(PartialEq, Eq,Debug)] |
| 2 | +pub enum PresentValueError{ |
| 3 | + NegetiveDiscount, |
| 4 | + EmptyCashFlow |
| 5 | +} |
| 6 | + |
| 7 | + |
| 8 | +pub fn present_value(discount_rate: f64, cash_flows: Vec<f64>) -> Result<f64, PresentValueError> { |
| 9 | + if discount_rate < 0.0 { |
| 10 | + return Err(PresentValueError::NegetiveDiscount); |
| 11 | + } |
| 12 | + if cash_flows.is_empty() { |
| 13 | + return Err(PresentValueError::EmptyCashFlow); |
| 14 | + } |
| 15 | + |
| 16 | + let present_value = cash_flows.iter().enumerate() |
| 17 | + .map(|(i, &cash_flow)| cash_flow / (1.0 + discount_rate).powi(i as i32)) |
| 18 | + .sum::<f64>(); |
| 19 | + |
| 20 | + Ok((present_value * 100.0).round() / 100.0) |
| 21 | +} |
| 22 | + |
| 23 | +#[cfg(test)] |
| 24 | +mod tests { |
| 25 | + use super::*; |
| 26 | + |
| 27 | + #[test] |
| 28 | + fn test_present_value() { |
| 29 | + |
| 30 | + assert_eq!(4.69,present_value(0.13, vec![10.0, 20.70, -293.0, 297.0]).unwrap()); |
| 31 | + |
| 32 | + assert_eq!( -42739.63,present_value(0.07, vec![-109129.39, 30923.23, 15098.93, 29734.0,39.0]).unwrap()); |
| 33 | + |
| 34 | + assert_eq!(175519.15,present_value(0.07, vec![109129.39, 30923.23, 15098.93, 29734.0,39.0]).unwrap()); |
| 35 | + } |
| 36 | + |
| 37 | + #[test] |
| 38 | + fn test_present_value_negative_discount_rate() { |
| 39 | + assert_eq!(PresentValueError::NegetiveDiscount,present_value(-1.0, vec![10.0, 20.70, -293.0, 297.0]).unwrap_err()); |
| 40 | + |
| 41 | + } |
| 42 | + |
| 43 | + #[test] |
| 44 | + fn test_present_value_empty_cash_flow() { |
| 45 | + assert_eq!(PresentValueError::EmptyCashFlow,present_value(1.0, vec![]).unwrap_err()); |
| 46 | + } |
| 47 | + |
| 48 | + #[test] |
| 49 | + fn test_present_value_zero_discount_rate() { |
| 50 | + assert_eq!(184924.55,present_value(0.0, vec![109129.39, 30923.23, 15098.93, 29734.0,39.0]).unwrap()); |
| 51 | + } |
| 52 | +} |
0 commit comments