use std::borrow::Cow;
use rust_i18n::t;
#[must_use]
pub fn location(code: &str) -> String {
let name: Cow<'_, str> = match code {
"ru-1" => t!("location.ru_1"),
"ru-2" => t!("location.ru_2"),
"ru-3" => t!("location.ru_3"),
"pl-1" => t!("location.pl_1"),
"kz-1" => t!("location.kz_1"),
"nl-1" => t!("location.nl_1"),
"de-1" => t!("location.de_1"),
_ => return code.to_string()
};
format!("{name} ({code})")
}
#[must_use]
pub fn date(iso: &str) -> String {
let Some((day, rest)) = iso.split_once('T') else {
return iso.to_string();
};
let time: String = rest.chars().take(5).collect();
format!("{day} {time}")
}
#[must_use]
pub fn megabytes(mb: i64) -> String {
if mb >= 1024 && mb % 1024 == 0 {
format!("{} GB", mb / 1024)
} else if mb >= 1024 {
#[expect(clippy::cast_precision_loss)]
let gb = mb as f64 / 1024.0;
format!("{gb:.1} GB")
} else {
format!("{mb} MB")
}
}
#[must_use]
pub fn bytes_rate(bytes_per_sec: f64) -> String {
let value = bytes_per_sec.max(0.0);
if value >= 1_048_576.0 {
format!("{:.1} MB/s", value / 1_048_576.0)
} else if value >= 1024.0 {
format!("{:.1} KB/s", value / 1024.0)
} else {
format!("{value:.0} B/s")
}
}
#[must_use]
pub fn count_resources(n: i32) -> String {
let key = match (n % 10, n % 100) {
(1, 1..=9 | 20..=99) => "resource_list.count_resources_one",
(2..=4, 1..=11 | 15..=99) => "resource_list.count_resources_few",
_ => "resource_list.count_resources_many"
};
rust_i18n::t!(key, n => n).into_owned()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn known_location_gets_a_name_with_code() {
let text = location("nl-1");
assert!(text.contains("nl-1"));
assert!(text.len() > "nl-1".len() + 3);
}
#[test]
fn unknown_location_passes_through() {
assert_eq!(location("xx-9"), "xx-9");
}
#[test]
fn iso_date_becomes_readable() {
assert_eq!(date("2026-06-08T02:33:05.000Z"), "2026-06-08 02:33");
assert_eq!(date("garbage"), "garbage");
}
#[test]
fn megabytes_scale_to_gigabytes() {
assert_eq!(megabytes(512), "512 MB");
assert_eq!(megabytes(20480), "20 GB");
assert_eq!(megabytes(1536), "1.5 GB");
}
}