use super::funejson::Value; use super::money_amount::{money, money_from_value, money_to_value, Money}; // Keeps annual rent exact as a JavaScript number; the same limit here. const MAX_MINOR: i64 = 1_000_000_000_000; /// One week's rent, the statutory maximum holding deposit: the annual rent /// divided by 52, rounded down once so the deposit can never exceed the cap. /// /// # Panics /// Panics on rent not in GBP or negative, or an unknown rent period. pub fn holding_deposit_cap(rent: &Money, rent_period: &str) -> Money { if rent.currency != "GBP" { panic!("rent must be in GBP, received {}", rent.currency); } if rent.minor < 0 { panic!("rent must not be negative, received {}", rent.minor); } let annual = match rent_period { "weekly" => rent.minor.checked_mul(52), "monthly" => rent.minor.checked_mul(12), "annual" => Some(rent.minor), other => panic!("unknown rent period \"{}\"", other), }; match annual { Some(a) if a <= MAX_MINOR => money(a / 52, "GBP"), _ => panic!("annual rent must be at most {} minor units", MAX_MINOR), } } pub fn fune_vector(args: &[Value]) -> Value { money_to_value(&holding_deposit_cap(&money_from_value(&args[0]), args[1].as_str())) }