use crate::number::format_decimal;
use crate::plural::{plural_category, PluralOperands};
use alloc::string::String;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(missing_docs)]
pub enum Unit {
Second,
Minute,
Hour,
Day,
Week,
Month,
Year,
Millimeter,
Centimeter,
Meter,
Kilometer,
Inch,
Foot,
Mile,
Gram,
Kilogram,
Ounce,
Pound,
Byte,
Kilobyte,
Megabyte,
Gigabyte,
Celsius,
Fahrenheit,
KilometerPerHour,
MilePerHour,
Liter,
Milliliter,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnitWidth {
Long,
Short,
}
fn operands(v: f64) -> PluralOperands {
if v % 1.0 == 0.0 && v > -1e15 && v < 1e15 {
PluralOperands::from_int(v as i64)
} else {
PluralOperands::parse(&alloc::format!("{v}")).unwrap_or(PluralOperands::from_int(v as i64))
}
}
#[must_use]
pub fn format_unit(lang: &str, value: f64, unit: Unit, width: UnitWidth) -> String {
let w = width as usize;
let u = unit as usize;
let cat = plural_category(lang, &operands(value)) as usize;
let norm: String = lang
.chars()
.map(|c| {
if c == '_' {
'-'
} else {
c.to_ascii_lowercase()
}
})
.collect();
let mut pattern = "{0}";
let mut end = norm.len();
loop {
if let Some(p) = crate::cldr::unit_pattern(&norm[..end], w, u, cat) {
pattern = p;
break;
}
match norm[..end].rfind('-') {
Some(i) => end = i,
None => {
if let Some(p) = crate::cldr::unit_pattern("en", w, u, cat) {
pattern = p;
}
break;
}
}
}
let number = format_decimal(lang, value);
pattern.replace("{0}", &number)
}
#[must_use]
pub fn format_duration(lang: &str, total_seconds: i64, width: UnitWidth) -> String {
let neg = total_seconds < 0;
let mut rem = total_seconds.unsigned_abs();
let parts = [
(86_400u64, Unit::Day),
(3_600, Unit::Hour),
(60, Unit::Minute),
(1, Unit::Second),
];
let mut out = String::new();
for (size, unit) in parts {
let v = rem / size;
rem %= size;
if v == 0 && !(unit == Unit::Second && out.is_empty()) {
continue;
}
if !out.is_empty() {
out.push(' ');
}
out.push_str(&format_unit(lang, v as f64, unit, width));
}
if neg {
let mut signed = String::from("-");
signed.push_str(&out);
signed
} else {
out
}
}