use rust_decimal::Decimal;
use rust_decimal_macros::dec;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InsuranceConfig {
pub percentage: Decimal,
}
impl Default for InsuranceConfig {
fn default() -> Self {
Self {
percentage: dec!(0.015),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InsuranceCalculator {
config: InsuranceConfig,
}
impl InsuranceCalculator {
pub fn new() -> Self {
Self::default()
}
pub fn with_config(config: InsuranceConfig) -> Self {
Self { config }
}
pub fn calculate(&self, pinjaman: Decimal) -> Decimal {
tracing::info!(
event = "calculate_insurance",
pinjaman = %pinjaman,
percentage = %self.config.percentage,
"Calculating insurance"
);
let asuransi = pinjaman * self.config.percentage;
tracing::info!(
event = "insurance_calculated",
asuransi = %asuransi,
"Insurance calculated"
);
asuransi
}
}
impl Default for InsuranceCalculator {
fn default() -> Self {
Self {
config: InsuranceConfig::default(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use rust_decimal_macros::dec;
#[test]
fn test_insurance_default_percentage() {
let calc = InsuranceCalculator::new();
let result = calc.calculate(dec!(10_000_000));
assert_eq!(result, dec!(150_000));
}
#[test]
fn test_insurance_custom_percentage() {
let config = InsuranceConfig {
percentage: dec!(0.02),
};
let calc = InsuranceCalculator::with_config(config);
let result = calc.calculate(dec!(5_000_000));
assert_eq!(result, dec!(100_000));
}
#[test]
fn test_insurance_zero_pinjaman() {
let calc = InsuranceCalculator::new();
let result = calc.calculate(dec!(0));
assert_eq!(result, dec!(0));
}
#[test]
fn test_insurance_decimal_precision() {
let calc = InsuranceCalculator::new();
let result = calc.calculate(dec!(1_000_000.50));
assert_eq!(result.to_string(), "15000.0075");
}
}