use crate::request_rate::duration_unit::DurationUnit;
use std::time::Duration;
pub fn rate_to_string(
numerator: u64,
duration: &Duration,
numerator_singular: &str,
numerator_plural: &str,
) -> String {
const MILLISECONDS_IN_A_SECOND: f64 = 1.0 / 0.001;
const SECONDS_IN_A_SECOND: f64 = 1.0;
const MINUTES_IN_A_SECOND: f64 = 1.0 / 60.0;
const HOURS_IN_A_SECOND: f64 = 1.0 / 3_600.0;
const DAYS_IN_A_SECOND: f64 = 1.0 / 86_400.0;
const WEEKS_IN_A_SECOND: f64 = 1.0 / 604_800.0;
const MONTHS_IN_A_SECOND: f64 = 1.0 / 2_629_746.0;
const YEARS_IN_A_SECOND: f64 = 1.0 / 31_556_952.0;
let duration_in_secs = duration.as_secs_f64();
let numerator = numerator as f64;
let adjusted_units = match duration_in_secs {
s if numerator / (s * MILLISECONDS_IN_A_SECOND) > 1.0 => (
numerator / (s * MILLISECONDS_IN_A_SECOND),
DurationUnit::Milliseconds,
),
s if numerator / (s * SECONDS_IN_A_SECOND) > 1.0 => {
(numerator / (s * SECONDS_IN_A_SECOND), DurationUnit::Seconds)
}
s if numerator / (s * MINUTES_IN_A_SECOND) > 1.0 => {
(numerator / (s * MINUTES_IN_A_SECOND), DurationUnit::Minutes)
}
s if numerator / (s * HOURS_IN_A_SECOND) > 1.0 => {
(numerator / (s * HOURS_IN_A_SECOND), DurationUnit::Hours)
}
s if numerator / (s * DAYS_IN_A_SECOND) > 1.0 => {
(numerator / (s * DAYS_IN_A_SECOND), DurationUnit::Days)
}
s if numerator / (s * WEEKS_IN_A_SECOND) > 1.0 => {
(numerator / (s * WEEKS_IN_A_SECOND), DurationUnit::Weeks)
}
s if numerator / (s * MONTHS_IN_A_SECOND) > 1.0 => {
(numerator / (s * MONTHS_IN_A_SECOND), DurationUnit::Months)
}
_ => (duration_in_secs * YEARS_IN_A_SECOND, DurationUnit::Years),
};
let mut quantity_string = match adjusted_units.0 {
q if q < 0.001 => format!("{q:.6}"),
q if q < 0.01 => format!("{q:.5}"),
q if q < 0.1 => format!("{q:.4}"),
q if q < 1.0 => format!("{q:.3}"),
q if q < 10.0 => format!("{q:.2}"),
q if q < 100.0 => format!("{q:.1}"),
_ => format!("{:.0}", adjusted_units.0),
};
if quantity_string.contains('.') {
quantity_string = quantity_string.trim_end_matches('0').to_string();
quantity_string = quantity_string.trim_end_matches('.').to_string();
}
let rate_type_string = if quantity_string == "1" {
numerator_singular
} else {
numerator_plural
};
let units_string = match adjusted_units.1 {
DurationUnit::Days => String::from("day"),
DurationUnit::Hours => String::from("hour"),
DurationUnit::Milliseconds => String::from("millisecond"),
DurationUnit::Minutes => String::from("minute"),
DurationUnit::Months => String::from("month"),
DurationUnit::Seconds => String::from("second"),
DurationUnit::Weeks => String::from("week"),
DurationUnit::Years => String::from("year"),
_ => adjusted_units.1.to_string(),
};
quantity_string + " " + rate_type_string + " per " + &units_string
}