use serde::{Deserialize, Serialize}; /// A label in a specific language (BCP-47 tag, e.g. "sv", "en"). #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct LocalizedLabel { pub lang: String, pub label: String, } /// Pick the best label for `lang`, falling back to `fallback`, then the first. pub fn pick_label<'a>(labels: &'a [LocalizedLabel], lang: &str, fallback: &str) -> Option<&'a str> { labels .iter() .find(|l| l.lang == lang) .or_else(|| labels.iter().find(|l| l.lang == fallback)) .or_else(|| labels.first()) .map(|l| l.label.as_str()) } #[cfg(test)] mod tests { use super::*; fn sample() -> Vec { vec![ LocalizedLabel { lang: "sv".into(), label: "trä".into(), }, LocalizedLabel { lang: "en".into(), label: "wood".into(), }, ] } #[test] fn prefers_requested_language() { assert_eq!(pick_label(&sample(), "sv", "en"), Some("trä")); } #[test] fn falls_back_then_first() { assert_eq!(pick_label(&sample(), "de", "en"), Some("wood")); assert_eq!(pick_label(&sample(), "de", "fr"), Some("trä")); assert_eq!(pick_label(&[], "sv", "en"), None); } }