diff --git a/src/locale_file_parser.rs b/src/locale_file_parser.rs index 9b2a7de..1480caa 100644 --- a/src/locale_file_parser.rs +++ b/src/locale_file_parser.rs @@ -12,24 +12,51 @@ const LOCALE_FILE_VERSION: i64 = 2; pub(crate) struct Translations { /// English pub(crate) en: Option, + /// Spanish + pub(crate) es: Option, + /// Chinese - Taiwan + pub(crate) zh_tw: Option, } impl Translations { + /// Construct a `Translations` with all fields set to `None`. + fn all_none() -> Self { + Self { + en: None, + es: None, + zh_tw: None, + } + } + /// Construct a [`Translation`] from the given `translation_mapping`. fn new(translation_yaml: Yaml) -> Self { match translation_yaml { - Yaml::Null => Self { en: None }, + Yaml::Null => Self::all_none(), Yaml::Mapping(mut translation_mapping) => { let en = { let opt_en_yaml = translation_mapping.remove("en"); opt_en_yaml.map(|opt_yaml| match opt_yaml { - Yaml::String(en) => en, + Yaml::String(str) => str, + _ => panic!("Error: translation should be string"), + }) + }; + let es = { + let opt_en_yaml = translation_mapping.remove("es"); + opt_en_yaml.map(|opt_yaml| match opt_yaml { + Yaml::String(str) => str, + _ => panic!("Error: translation should be string"), + }) + }; + let zh_tw = { + let opt_en_yaml = translation_mapping.remove("zh_TW"); + opt_en_yaml.map(|opt_yaml| match opt_yaml { + Yaml::String(str) => str, _ => panic!("Error: translation should be string"), }) }; - Self { en } + Self { en, es, zh_tw } } _ => panic!("Error: invalid format for translation"), @@ -122,17 +149,21 @@ _version: 1 _version: 2 "with_no_en": "with_en": - en: "with_en""#; + en: "with_en" + es: "with_es" + zh_TW: "with_zh_TW""#; let yaml: Yaml = serde_yaml_ng::from_str(yaml_str).unwrap(); let parsed = LocalizedTexts::new(yaml); let expected = LocalizedTexts { texts: IndexMap::from_iter(vec![ - ("with_no_en".to_string(), Translations { en: None }), + ("with_no_en".to_string(), Translations::all_none()), ( "with_en".to_string(), Translations { en: Some("with_en".to_string()), + es: Some("with_es".to_string()), + zh_tw: Some("with_zh_TW".to_string()), }, ), ]), diff --git a/src/rules/key_and_eng_matches.rs b/src/rules/key_and_eng_matches.rs index 2962548..de3e571 100644 --- a/src/rules/key_and_eng_matches.rs +++ b/src/rules/key_and_eng_matches.rs @@ -299,7 +299,14 @@ mod tests { #[test] fn test_rule_works_missing_en_translation() { let localized_texts = LocalizedTexts { - texts: IndexMap::from([("Restarting".into(), Translations { en: None })]), + texts: IndexMap::from([( + "Restarting".into(), + Translations { + en: None, + es: Some("ff".into()), + zh_tw: Some("bar".into()), + }, + )]), }; let rule = KeyEngMatches; let mut errors = HashMap::new(); @@ -321,6 +328,8 @@ mod tests { "Restarting".into(), Translations { en: Some("buz".into()), + es: Some("buz".into()), + zh_tw: Some("buz".into()), }, )]), }; @@ -341,6 +350,8 @@ mod tests { "Restarting {app}".into(), Translations { en: Some("Restarting {app}".into()), + es: Some("Restarting {app}".into()), + zh_tw: Some("Restarting {app}".into()), }, )]), }; @@ -361,6 +372,8 @@ mod tests { "Restarting {app}".into(), Translations { en: Some("Restarting %{app}".into()), + es: Some("Restarting %{app}".into()), + zh_tw: Some("Restarting %{app}".into()), }, )]), }; @@ -375,6 +388,8 @@ mod tests { "Restarting".into(), Translations { en: Some("Restarting".into()), + es: Some("Restarting".into()), + zh_tw: Some("Restarting".into()), }, )]), }; diff --git a/src/rules/missing_translations.rs b/src/rules/missing_translations.rs index 10dabf1..22dddd0 100644 --- a/src/rules/missing_translations.rs +++ b/src/rules/missing_translations.rs @@ -10,7 +10,9 @@ bitflags! { /// When a language is missing, its bit will be set to 1. #[derive(Debug, PartialEq, Eq)] struct MissingLanguages: u8 { - const En = 0b_0000_0001; + const En = 0b_0000_0001; + const Es = 0b_0000_0010; + const ZhTW = 0b_0000_0100; } } @@ -21,7 +23,13 @@ impl MissingLanguages { str.push('['); for lang in self.iter() { if lang == MissingLanguages::En { - str.push_str("English") + str.push_str("en") + } + if lang == MissingLanguages::Es { + str.push_str(", es"); + } + if lang == MissingLanguages::ZhTW { + str.push_str(", zh_TW"); } } str.push(']'); @@ -46,6 +54,12 @@ impl Rule for MissingTranslations { if translations.en.is_none() { missing_langs.insert(MissingLanguages::En); } + if translations.es.is_none() { + missing_langs.insert(MissingLanguages::Es); + } + if translations.zh_tw.is_none() { + missing_langs.insert(MissingLanguages::ZhTW); + } if !missing_langs.is_empty() { Self::report_error(key.clone(), Some(missing_langs.error_msg()), errors); @@ -61,15 +75,31 @@ mod tests { use indexmap::IndexMap; #[test] - fn test_missing_en() { + fn test_missing_translations() { let localized_texts = LocalizedTexts { texts: IndexMap::from([ - ("Restarting {app}".into(), Translations { en: None }), - ("Restarting {topgrade}".into(), Translations { en: None }), + ( + "Restarting {app}".into(), + Translations { + en: None, + es: None, + zh_tw: Some("c".into()), + }, + ), + ( + "Restarting {topgrade}".into(), + Translations { + en: None, + es: Some("c".into()), + zh_tw: None, + }, + ), ( "Restarting {ba}".into(), Translations { en: Some("Restarting %{ba}".into()), + es: Some("Restarting %{ba}".into()), + zh_tw: Some("Restarting %{ba}".into()), }, ), ]), @@ -82,11 +112,11 @@ mod tests { vec![ ( "Restarting {app}".to_string(), - Some("Missing translations for [English]".into()), + Some("Missing translations for [en, es]".into()), ), ( "Restarting {topgrade}".to_string(), - Some("Missing translations for [English]".into()), + Some("Missing translations for [en, zh_TW]".into()), ), ], )]); @@ -101,18 +131,24 @@ mod tests { "Restarting {app}".into(), Translations { en: Some("whatever".into()), + es: Some("whatever".into()), + zh_tw: Some("whatever".into()), }, ), ( "Restarting {topgrade}".into(), Translations { en: Some("wahtever".into()), + es: Some("wahtever".into()), + zh_tw: Some("wahtever".into()), }, ), ( "Restarting {ba}".into(), Translations { en: Some("Restarting %{ba}".into()), + es: Some("Restarting %{ba}".into()), + zh_tw: Some("Restarting %{ba}".into()), }, ), ]), diff --git a/src/rules/use_of_keys_do_not_exist.rs b/src/rules/use_of_keys_do_not_exist.rs index 80265da..8dbe1fd 100644 --- a/src/rules/use_of_keys_do_not_exist.rs +++ b/src/rules/use_of_keys_do_not_exist.rs @@ -69,6 +69,8 @@ mod tests { "Restarting".into(), Translations { en: Some("Restarting".into()), + es: Some("Restarting".into()), + zh_tw: Some("Restarting".into()), }, )]), };