use super::Entry;
pub(super) fn tr(key: &str) -> Option<Entry> {
tr_general(key)
.or_else(|| tr_paths_and_naming(key))
.or_else(|| tr_sidecar(key))
.or_else(|| tr_classification(key))
.or_else(|| tr_storage_mode_options(key))
.or_else(|| tr_verschlusssache_nato(key))
.or_else(|| tr_publisher(key))
.or_else(|| tr_actions(key))
.or_else(|| tr_validation_fields(key))
.or_else(|| tr_validation_publisher_classification(key))
}
fn tr_general(key: &str) -> Option<Entry> {
Some(match key {
"settings.section_general" => ("General", "Allgemein", "Général", "General", "Generale"),
"settings.csaf_mode_label" => (
"CSAF Mode *",
"CSAF-Modus *",
"Mode CSAF *",
"Modo CSAF *",
"Modalità CSAF *",
),
"settings.csaf_mode_help" => (
"Determines validation rules and the <code>csaf_version</code> written into exported files.",
"Bestimmt die Validierungsregeln und die in exportierte Dateien geschriebene <code>csaf_version</code>.",
"Détermine les règles de validation et la <code>csaf_version</code> écrite dans les fichiers exportés.",
"Determina las reglas de validación y la <code>csaf_version</code> escrita en los archivos exportados.",
"Determina le regole di convalida e il valore <code>csaf_version</code> scritto nei file esportati.",
),
"settings.theme_label" => ("Theme", "Design", "Thème", "Tema", "Tema"),
"settings.theme_help" => (
"You can also use the toggle in the top navigation bar.",
"Sie können auch den Schalter in der oberen Navigationsleiste verwenden.",
"Vous pouvez également utiliser le bouton dans la barre de navigation supérieure.",
"También puede usar el interruptor en la barra de navegación superior.",
"È possibile utilizzare anche l'interruttore nella barra di navigazione superiore.",
),
"settings.import_directory_label" => (
"Import Directory",
"Import-Verzeichnis",
"Répertoire d'importation",
"Directorio de importación",
"Directory di importazione",
),
"settings.import_directory_help" => (
"Filesystem path scanned for CSAF JSON files during import.",
"Dateisystempfad, der beim Import nach CSAF-JSON-Dateien durchsucht wird.",
"Chemin du système de fichiers analysé pour les fichiers JSON CSAF lors de l'importation.",
"Ruta del sistema de archivos examinada en busca de archivos JSON CSAF durante la importación.",
"Percorso del file system analizzato per i file JSON CSAF durante l'importazione.",
),
"settings.export_directory_label" => (
"Export Directory",
"Export-Verzeichnis",
"Répertoire d'exportation",
"Directorio de exportación",
"Directory di esportazione",
),
"settings.export_directory_help" => (
"Filesystem path where exported CSAF files and sidecars are written.",
"Dateisystempfad, in den exportierte CSAF-Dateien und Sidecar-Dateien geschrieben werden.",
"Chemin du système de fichiers où sont écrits les fichiers CSAF exportés et leurs fichiers sidecar.",
"Ruta del sistema de archivos donde se escriben los archivos CSAF exportados y sus archivos sidecar.",
"Percorso del file system in cui vengono scritti i file CSAF esportati e i relativi file sidecar.",
),
_ => return None,
})
}
fn tr_paths_and_naming(key: &str) -> Option<Entry> {
Some(match key {
"settings.dump_directory_label" => (
"Dump Directory",
"Dump-Verzeichnis",
"Répertoire de vidage",
"Directorio de volcado",
"Directory di dump",
),
"settings.dump_directory_help" => (
"Filesystem path where the database dump files and sidecars are written.",
"Dateisystempfad, in den die Datenbank-Dump-Dateien und Sidecar-Dateien geschrieben werden.",
"Chemin du système de fichiers où sont écrits les fichiers de vidage de la base de données et leurs fichiers sidecar.",
"Ruta del sistema de archivos donde se escriben los archivos de volcado de la base de datos y sus archivos sidecar.",
"Percorso del file system in cui vengono scritti i file di dump del database e i relativi file sidecar.",
),
"settings.log_directory_label" => (
"Log Directory",
"Protokoll-Verzeichnis",
"Répertoire des journaux",
"Directorio de registros",
"Directory dei log",
),
"settings.log_directory_help" => (
"Filesystem path where the application log files and sidecars are written.",
"Dateisystempfad, in den die Anwendungsprotokolldateien und Sidecar-Dateien geschrieben werden.",
"Chemin du système de fichiers où sont écrits les fichiers journaux de l'application et leurs fichiers sidecar.",
"Ruta del sistema de archivos donde se escriben los archivos de registro de la aplicación y sus archivos sidecar.",
"Percorso del file system in cui vengono scritti i file di log dell'applicazione e i relativi file sidecar.",
),
"settings.naming_convention_label" => (
"Naming Convention Prefix",
"Präfix der Namenskonvention",
"Préfixe de la convention de nommage",
"Prefijo de la convención de nomenclatura",
"Prefisso della convenzione di denominazione",
),
"settings.naming_convention_help" => (
"Prefix used for tracking IDs (e.g. <code>ndaal-sa-</code>).",
"Präfix für Tracking-IDs (z. B. <code>ndaal-sa-</code>).",
"Préfixe utilisé pour les identifiants de suivi (par ex. <code>ndaal-sa-</code>).",
"Prefijo utilizado para los identificadores de seguimiento (p. ej., <code>ndaal-sa-</code>).",
"Prefisso utilizzato per gli ID di tracciamento (ad es. <code>ndaal-sa-</code>).",
),
_ => return None,
})
}
fn tr_sidecar(key: &str) -> Option<Entry> {
Some(match key {
"settings.sidecar_hash_files_label" => (
"Sidecar Hash Files",
"Sidecar-Hash-Dateien",
"Fichiers de hachage sidecar",
"Archivos hash sidecar",
"File hash sidecar",
),
"settings.sidecar_sha256_label" => (
"Generate SHA-256 hashes sidecars (extension <code>.sha-256</code>)",
"SHA-256-Hash-Sidecars erzeugen (Erweiterung <code>.sha-256</code>)",
"Générer les fichiers sidecar de hachage SHA-256 (extension <code>.sha-256</code>)",
"Generar archivos sidecar de hash SHA-256 (extensión <code>.sha-256</code>)",
"Genera i sidecar hash SHA-256 (estensione <code>.sha-256</code>)",
),
"settings.sidecar_sha512_label" => (
"Generate SHA-512 hashes sidecars (extension <code>.sha-512</code>)",
"SHA-512-Hash-Sidecars erzeugen (Erweiterung <code>.sha-512</code>)",
"Générer les fichiers sidecar de hachage SHA-512 (extension <code>.sha-512</code>)",
"Generar archivos sidecar de hash SHA-512 (extensión <code>.sha-512</code>)",
"Genera i sidecar hash SHA-512 (estensione <code>.sha-512</code>)",
),
"settings.sidecar_sha3_512_label" => (
"Generate SHA3-512 hashes sidecars (extension <code>.sha3-512</code>)",
"SHA3-512-Hash-Sidecars erzeugen (Erweiterung <code>.sha3-512</code>)",
"Générer les fichiers sidecar de hachage SHA3-512 (extension <code>.sha3-512</code>)",
"Generar archivos sidecar de hash SHA3-512 (extensión <code>.sha3-512</code>)",
"Genera i sidecar hash SHA3-512 (estensione <code>.sha3-512</code>)",
),
"settings.sidecar_blake3_512_label" => (
"Generate BLAKE3-512 hashes sidecars (extension <code>.blake3-512</code>)",
"BLAKE3-512-Hash-Sidecars erzeugen (Erweiterung <code>.blake3-512</code>)",
"Générer les fichiers sidecar de hachage BLAKE3-512 (extension <code>.blake3-512</code>)",
"Generar archivos sidecar de hash BLAKE3-512 (extensión <code>.blake3-512</code>)",
"Genera i sidecar hash BLAKE3-512 (estensione <code>.blake3-512</code>)",
),
"settings.sidecar_shake256_512_label" => (
"Generate SHAKE256-512 hashes sidecars (extension <code>.shake256-512</code>)",
"SHAKE256-512-Hash-Sidecars erzeugen (Erweiterung <code>.shake256-512</code>)",
"Générer les fichiers sidecar de hachage SHAKE256-512 (extension <code>.shake256-512</code>)",
"Generar archivos sidecar de hash SHAKE256-512 (extensión <code>.shake256-512</code>)",
"Genera i sidecar hash SHAKE256-512 (estensione <code>.shake256-512</code>)",
),
_ => return None,
})
}
fn tr_classification(key: &str) -> Option<Entry> {
Some(match key {
"settings.section_classification" => (
"Classification",
"Einstufung",
"Classification",
"Clasificación",
"Classificazione",
),
"settings.classification_intro" => (
"Defaults for the colored TLP 2.0 selector, the German Verschlusssache field, and the NATO classification field. These values prefill the CSAF create form; per-document overrides are still possible.",
"Standardwerte für den farbigen TLP-2.0-Selektor, das deutsche Verschlusssache-Feld und das NATO-Einstufungsfeld. Diese Werte werden in das CSAF-Erstellungsformular vorausgefüllt; Überschreibungen pro Dokument sind weiterhin möglich.",
"Valeurs par défaut pour le sélecteur coloré TLP 2.0, le champ Verschlusssache allemand et le champ de classification NATO. Ces valeurs préremplissent le formulaire de création CSAF ; une substitution par document reste possible.",
"Valores predeterminados para el selector de colores TLP 2.0, el campo Verschlusssache alemán y el campo de clasificación NATO. Estos valores prellenan el formulario de creación de CSAF; aún es posible anularlos por documento.",
"Valori predefiniti per il selettore colorato TLP 2.0, il campo Verschlusssache tedesco e il campo di classificazione NATO. Questi valori precompilano il modulo di creazione CSAF; è comunque possibile sovrascriverli per singolo documento.",
),
"settings.tlp_default_label" => (
"TLP 2.0 default *",
"TLP-2.0-Standard *",
"Valeur TLP 2.0 par défaut *",
"Valor predeterminado de TLP 2.0 *",
"Valore predefinito TLP 2.0 *",
),
"settings.tlp_default_help" => (
r#"Colour-coding per <a href="https://www.first.org/tlp/" target="_blank" rel="noopener">FIRST TLP 2.0</a>."#,
r#"Farbcodierung gemäß <a href="https://www.first.org/tlp/" target="_blank" rel="noopener">FIRST TLP 2.0</a>."#,
r#"Codage couleur selon <a href="https://www.first.org/tlp/" target="_blank" rel="noopener">FIRST TLP 2.0</a>."#,
r#"Codificación por colores según <a href="https://www.first.org/tlp/" target="_blank" rel="noopener">FIRST TLP 2.0</a>."#,
r#"Codifica a colori secondo <a href="https://www.first.org/tlp/" target="_blank" rel="noopener">FIRST TLP 2.0</a>."#,
),
"settings.storage_mode_label" => (
"Storage mode *",
"Speichermodus *",
"Mode de stockage *",
"Modo de almacenamiento *",
"Modalità di archiviazione *",
),
"settings.storage_mode_help" => (
"Where to write Verschlusssache / NATO values in the exported CSAF JSON. <code>both</code> writes to <code>document.distribution.text</code> AND <code>document.notes[]</code> so any consumer can find them.",
"Legt fest, wohin Verschlusssache-/NATO-Werte im exportierten CSAF-JSON geschrieben werden. <code>both</code> schreibt in <code>document.distribution.text</code> UND <code>document.notes[]</code>, damit jeder Konsument sie findet.",
"Indique où écrire les valeurs Verschlusssache / NATO dans le CSAF JSON exporté. <code>both</code> écrit dans <code>document.distribution.text</code> ET <code>document.notes[]</code> afin que tout consommateur puisse les trouver.",
"Indica dónde escribir los valores Verschlusssache/NATO en el CSAF JSON exportado. <code>both</code> escribe en <code>document.distribution.text</code> Y <code>document.notes[]</code> para que cualquier consumidor pueda encontrarlos.",
"Indica dove scrivere i valori Verschlusssache/NATO nel CSAF JSON esportato. <code>both</code> scrive in <code>document.distribution.text</code> E <code>document.notes[]</code> in modo che qualsiasi consumer possa trovarli.",
),
_ => return None,
})
}
fn tr_storage_mode_options(key: &str) -> Option<Entry> {
Some(match key {
"settings.storage_mode_option_distribution_text" => (
"Only document.distribution.text",
"Nur document.distribution.text",
"Uniquement document.distribution.text",
"Solo document.distribution.text",
"Solo document.distribution.text",
),
"settings.storage_mode_option_notes" => (
"Only document.notes[]",
"Nur document.notes[]",
"Uniquement document.notes[]",
"Solo document.notes[]",
"Solo document.notes[]",
),
"settings.storage_mode_option_both" => (
"Both (distribution.text AND notes[])",
"Beide (distribution.text UND notes[])",
"Les deux (distribution.text ET notes[])",
"Ambos (distribution.text Y notes[])",
"Entrambi (distribution.text E notes[])",
),
_ => return None,
})
}
fn tr_verschlusssache_nato(key: &str) -> Option<Entry> {
Some(match key {
"settings.verschlusssache_enable_label" => (
"Enable Verschlusssache",
"Verschlusssache aktivieren",
"Activer Verschlusssache",
"Habilitar Verschlusssache",
"Abilita Verschlusssache",
),
"settings.verschlusssache_default_label" => (
"Verschlusssache default",
"Verschlusssache-Standard",
"Valeur Verschlusssache par défaut",
"Valor Verschlusssache predeterminado",
"Valore Verschlusssache predefinito",
),
"settings.verschlusssache_default_help" => (
r#"German national classification per <a href="https://de.wikipedia.org/wiki/Verschlusssache#Einstufung" target="_blank" rel="noopener">§ Verschlusssache</a>."#,
r#"Deutsche nationale Einstufung gemäß <a href="https://de.wikipedia.org/wiki/Verschlusssache#Einstufung" target="_blank" rel="noopener">§ Verschlusssache</a>."#,
r#"Classification nationale allemande selon <a href="https://de.wikipedia.org/wiki/Verschlusssache#Einstufung" target="_blank" rel="noopener">§ Verschlusssache</a>."#,
r#"Clasificación nacional alemana según <a href="https://de.wikipedia.org/wiki/Verschlusssache#Einstufung" target="_blank" rel="noopener">§ Verschlusssache</a>."#,
r#"Classificazione nazionale tedesca secondo <a href="https://de.wikipedia.org/wiki/Verschlusssache#Einstufung" target="_blank" rel="noopener">§ Verschlusssache</a>."#,
),
"settings.nato_enable_label" => (
"Enable NATO",
"NATO aktivieren",
"Activer NATO",
"Habilitar NATO",
"Abilita NATO",
),
"settings.nato_default_label" => (
"NATO default",
"NATO-Standard",
"Valeur NATO par défaut",
"Valor NATO predeterminado",
"Valore NATO predefinito",
),
"settings.nato_default_help" => (
r#"NATO classification per <a href="https://de.wikipedia.org/wiki/Geheimhaltungsgrad#NATO" target="_blank" rel="noopener">§ Geheimhaltungsgrad</a>."#,
r#"NATO-Einstufung gemäß <a href="https://de.wikipedia.org/wiki/Geheimhaltungsgrad#NATO" target="_blank" rel="noopener">§ Geheimhaltungsgrad</a>."#,
r#"Classification NATO selon <a href="https://de.wikipedia.org/wiki/Geheimhaltungsgrad#NATO" target="_blank" rel="noopener">§ Geheimhaltungsgrad</a>."#,
r#"Clasificación NATO según <a href="https://de.wikipedia.org/wiki/Geheimhaltungsgrad#NATO" target="_blank" rel="noopener">§ Geheimhaltungsgrad</a>."#,
r#"Classificazione NATO secondo <a href="https://de.wikipedia.org/wiki/Geheimhaltungsgrad#NATO" target="_blank" rel="noopener">§ Geheimhaltungsgrad</a>."#,
),
_ => return None,
})
}
fn tr_publisher(key: &str) -> Option<Entry> {
Some(match key {
"settings.section_publisher" => (
"Publisher Defaults",
"Herausgeber-Standardwerte",
"Valeurs par défaut de l'éditeur",
"Valores predeterminados del editor",
"Valori predefiniti dell'editore",
),
"settings.publisher_intro" => (
"These values are prefilled into the CSAF create form and inherited by every new document. You can still override them per document at creation time.",
"Diese Werte werden in das CSAF-Erstellungsformular vorausgefüllt und von jedem neuen Dokument übernommen. Sie können sie bei der Erstellung weiterhin pro Dokument überschreiben.",
"Ces valeurs préremplissent le formulaire de création CSAF et sont héritées par chaque nouveau document. Vous pouvez toujours les remplacer par document lors de la création.",
"Estos valores prellenan el formulario de creación de CSAF y se heredan en cada documento nuevo. Aún puede anularlos por documento en el momento de la creación.",
"Questi valori precompilano il modulo di creazione CSAF e vengono ereditati da ogni nuovo documento. È comunque possibile sovrascriverli per singolo documento al momento della creazione.",
),
"settings.publisher_name_label" => ("Name *", "Name *", "Nom *", "Nombre *", "Nome *"),
"settings.publisher_namespace_label" => (
"Namespace *",
"Namensraum *",
"Espace de noms *",
"Espacio de nombres *",
"Spazio dei nomi *",
),
"settings.publisher_category_label" => (
"Category *",
"Kategorie *",
"Catégorie *",
"Categoría *",
"Categoria *",
),
"settings.publisher_category_help" => (
"OASIS CSAF publisher category.",
"OASIS-CSAF-Herausgeberkategorie.",
"Catégorie d'éditeur OASIS CSAF.",
"Categoría de editor OASIS CSAF.",
"Categoria dell'editore OASIS CSAF.",
),
"settings.publisher_contact_label" => (
"Contact details",
"Kontaktdaten",
"Coordonnées de contact",
"Datos de contacto",
"Dati di contatto",
),
"settings.publisher_contact_help" => (
"Usually an email address or security contact URL.",
"In der Regel eine E-Mail-Adresse oder eine URL für den Sicherheitskontakt.",
"Généralement une adresse e-mail ou une URL de contact sécurité.",
"Normalmente una dirección de correo electrónico o una URL de contacto de seguridad.",
"Di solito un indirizzo e-mail o un URL di contatto per la sicurezza.",
),
_ => return None,
})
}
fn tr_actions(key: &str) -> Option<Entry> {
Some(match key {
"settings.save_button" => (
"Save Settings",
"Einstellungen speichern",
"Enregistrer les paramètres",
"Guardar configuración",
"Salva impostazioni",
),
"settings.reset_button" => (
"Reset to default settings",
"Auf Standardeinstellungen zurücksetzen",
"Réinitialiser aux paramètres par défaut",
"Restablecer a la configuración predeterminada",
"Ripristina le impostazioni predefinite",
),
"settings.reset_help" => (
"Restores every field on this page to the application defaults.",
"Setzt alle Felder auf dieser Seite auf die Anwendungsstandardwerte zurück.",
"Réinitialise tous les champs de cette page aux valeurs par défaut de l'application.",
"Restaura todos los campos de esta página a los valores predeterminados de la aplicación.",
"Ripristina tutti i campi di questa pagina ai valori predefiniti dell'applicazione.",
),
"settings.reset_confirm" => (
"Reset ALL settings to their default values? This cannot be undone.",
"Sollen ALLE Einstellungen auf ihre Standardwerte zurückgesetzt werden? Dies kann nicht rückgängig gemacht werden.",
"Réinitialiser TOUS les paramètres à leurs valeurs par défaut ? Cette action est irréversible.",
"¿Restablecer TODOS los ajustes a sus valores predeterminados? Esta acción no se puede deshacer.",
"Ripristinare TUTTE le impostazioni ai valori predefiniti? Questa azione non può essere annullata.",
),
_ => return None,
})
}
fn tr_validation_fields(key: &str) -> Option<Entry> {
Some(match key {
"settings.err_csaf_mode" => (
"CSAF mode must be '2.0' or '2.1'.",
"Der CSAF-Modus muss '2.0' oder '2.1' sein.",
"Le mode CSAF doit être '2.0' ou '2.1'.",
"El modo CSAF debe ser '2.0' o '2.1'.",
"La modalità CSAF deve essere '2.0' o '2.1'.",
),
"settings.err_theme" => (
"Theme must be 'light' or 'dark'.",
"Das Design muss 'light' oder 'dark' sein.",
"Le thème doit être 'light' ou 'dark'.",
"El tema debe ser 'light' o 'dark'.",
"Il tema deve essere 'light' o 'dark'.",
),
"settings.err_import_directory" => (
"Import Directory contains invalid or unsafe path characters.",
"Das Import-Verzeichnis enthält ungültige oder unsichere Pfadzeichen.",
"Le répertoire d'importation contient des caractères de chemin non valides ou dangereux.",
"El directorio de importación contiene caracteres de ruta no válidos o inseguros.",
"La directory di importazione contiene caratteri di percorso non validi o non sicuri.",
),
"settings.err_export_directory" => (
"Export Directory contains invalid or unsafe path characters.",
"Das Export-Verzeichnis enthält ungültige oder unsichere Pfadzeichen.",
"Le répertoire d'exportation contient des caractères de chemin non valides ou dangereux.",
"El directorio de exportación contiene caracteres de ruta no válidos o inseguros.",
"La directory di esportazione contiene caratteri di percorso non validi o non sicuri.",
),
"settings.err_dump_directory" => (
"Dump Directory contains invalid or unsafe path characters.",
"Das Dump-Verzeichnis enthält ungültige oder unsichere Pfadzeichen.",
"Le répertoire de vidage contient des caractères de chemin non valides ou dangereux.",
"El directorio de volcado contiene caracteres de ruta no válidos o inseguros.",
"La directory di dump contiene caratteri di percorso non validi o non sicuri.",
),
"settings.err_log_directory" => (
"Log Directory contains invalid or unsafe path characters.",
"Das Protokoll-Verzeichnis enthält ungültige oder unsichere Pfadzeichen.",
"Le répertoire des journaux contient des caractères de chemin non valides ou dangereux.",
"El directorio de registros contiene caracteres de ruta no válidos o inseguros.",
"La directory dei log contiene caratteri di percorso non validi o non sicuri.",
),
_ => return None,
})
}
fn tr_validation_publisher_classification(key: &str) -> Option<Entry> {
Some(match key {
"settings.err_publisher_name" => (
"Publisher name must not be empty.",
"Der Herausgebername darf nicht leer sein.",
"Le nom de l'éditeur ne doit pas être vide.",
"El nombre del editor no debe estar vacío.",
"Il nome dell'editore non deve essere vuoto.",
),
"settings.err_publisher_namespace" => (
"Publisher namespace must not be empty.",
"Der Herausgeber-Namensraum darf nicht leer sein.",
"L'espace de noms de l'éditeur ne doit pas être vide.",
"El espacio de nombres del editor no debe estar vacío.",
"Lo spazio dei nomi dell'editore non deve essere vuoto.",
),
"settings.err_publisher_category" => (
"Publisher category must be one of: vendor, discoverer, coordinator, user, translator, other.",
"Die Herausgeberkategorie muss eine der folgenden sein: vendor, discoverer, coordinator, user, translator, other.",
"La catégorie d'éditeur doit être l'une des suivantes : vendor, discoverer, coordinator, user, translator, other.",
"La categoría de editor debe ser una de las siguientes: vendor, discoverer, coordinator, user, translator, other.",
"La categoria dell'editore deve essere una tra: vendor, discoverer, coordinator, user, translator, other.",
),
"settings.err_tlp_default" => (
"TLP 2.0 default must be one of: CLEAR, GREEN, AMBER, AMBER+STRICT, RED.",
"Der TLP-2.0-Standard muss einer der folgenden sein: CLEAR, GREEN, AMBER, AMBER+STRICT, RED.",
"La valeur TLP 2.0 par défaut doit être l'une des suivantes : CLEAR, GREEN, AMBER, AMBER+STRICT, RED.",
"El valor predeterminado de TLP 2.0 debe ser uno de los siguientes: CLEAR, GREEN, AMBER, AMBER+STRICT, RED.",
"Il valore predefinito TLP 2.0 deve essere uno tra: CLEAR, GREEN, AMBER, AMBER+STRICT, RED.",
),
"settings.err_verschlusssache_default" => (
"Verschlusssache default must be one of the four official German classification labels.",
"Der Verschlusssache-Standard muss eine der vier offiziellen deutschen Einstufungsbezeichnungen sein.",
"La valeur Verschlusssache par défaut doit être l'une des quatre classifications officielles allemandes.",
"El valor Verschlusssache predeterminado debe ser una de las cuatro etiquetas de clasificación oficiales alemanas.",
"Il valore Verschlusssache predefinito deve essere una delle quattro etichette di classificazione ufficiali tedesche.",
),
"settings.err_nato_default" => (
"NATO default must be one of: NR (NATO RESTRICTED), NC (NATO CONFIDENTIAL), NS (NATO SECRET), CTS (COSMIC TOP SECRET).",
"Der NATO-Standard muss einer der folgenden sein: NR (NATO RESTRICTED), NC (NATO CONFIDENTIAL), NS (NATO SECRET), CTS (COSMIC TOP SECRET).",
"La valeur NATO par défaut doit être l'une des suivantes : NR (NATO RESTRICTED), NC (NATO CONFIDENTIAL), NS (NATO SECRET), CTS (COSMIC TOP SECRET).",
"El valor NATO predeterminado debe ser uno de los siguientes: NR (NATO RESTRICTED), NC (NATO CONFIDENTIAL), NS (NATO SECRET), CTS (COSMIC TOP SECRET).",
"Il valore NATO predefinito deve essere uno tra: NR (NATO RESTRICTED), NC (NATO CONFIDENTIAL), NS (NATO SECRET), CTS (COSMIC TOP SECRET).",
),
"settings.err_classification_storage_mode" => (
"Classification storage mode must be 'distribution_text', 'notes', or 'both'.",
"Der Speichermodus für die Einstufung muss 'distribution_text', 'notes' oder 'both' sein.",
"Le mode de stockage de la classification doit être 'distribution_text', 'notes' ou 'both'.",
"El modo de almacenamiento de la clasificación debe ser 'distribution_text', 'notes' o 'both'.",
"La modalità di archiviazione della classificazione deve essere 'distribution_text', 'notes' o 'both'.",
),
_ => return None,
})
}
#[cfg(test)]
mod tests {
use super::super::{Lang, t};
use super::*;
const ALL_KEYS: &[&str] = &[
"settings.section_general",
"settings.csaf_mode_label",
"settings.csaf_mode_help",
"settings.theme_label",
"settings.theme_help",
"settings.import_directory_label",
"settings.import_directory_help",
"settings.export_directory_label",
"settings.export_directory_help",
"settings.dump_directory_label",
"settings.dump_directory_help",
"settings.log_directory_label",
"settings.log_directory_help",
"settings.naming_convention_label",
"settings.naming_convention_help",
"settings.sidecar_hash_files_label",
"settings.sidecar_sha256_label",
"settings.sidecar_sha512_label",
"settings.sidecar_sha3_512_label",
"settings.sidecar_blake3_512_label",
"settings.sidecar_shake256_512_label",
"settings.section_classification",
"settings.classification_intro",
"settings.tlp_default_label",
"settings.tlp_default_help",
"settings.storage_mode_label",
"settings.storage_mode_help",
"settings.storage_mode_option_distribution_text",
"settings.storage_mode_option_notes",
"settings.storage_mode_option_both",
"settings.verschlusssache_enable_label",
"settings.verschlusssache_default_label",
"settings.verschlusssache_default_help",
"settings.nato_enable_label",
"settings.nato_default_label",
"settings.nato_default_help",
"settings.section_publisher",
"settings.publisher_intro",
"settings.publisher_name_label",
"settings.publisher_namespace_label",
"settings.publisher_category_label",
"settings.publisher_category_help",
"settings.publisher_contact_label",
"settings.publisher_contact_help",
"settings.save_button",
"settings.reset_button",
"settings.reset_help",
"settings.reset_confirm",
"settings.err_csaf_mode",
"settings.err_theme",
"settings.err_import_directory",
"settings.err_export_directory",
"settings.err_dump_directory",
"settings.err_log_directory",
"settings.err_publisher_name",
"settings.err_publisher_namespace",
"settings.err_publisher_category",
"settings.err_tlp_default",
"settings.err_verschlusssache_default",
"settings.err_nato_default",
"settings.err_classification_storage_mode",
];
const PROTOCOL_FIXED_VALUES: &[&str] = &[
"CLEAR",
"GREEN",
"AMBER",
"AMBER+STRICT",
"RED",
"VS-NfD (VS-NUR FÜR DEN DIENSTGEBRAUCH)",
"VS-Vertr. (VS-VERTRAULICH)",
"Geh. (GEHEIM)",
"Str. Geh. (STRENG GEHEIM)",
"NR (NATO RESTRICTED)",
"NC (NATO CONFIDENTIAL)",
"NS (NATO SECRET)",
"CTS (COSMIC TOP SECRET)",
"distribution_text",
"notes",
"both",
"2.0",
"2.1",
"light",
"dark",
"vendor",
"discoverer",
"coordinator",
"user",
"translator",
"other",
];
#[test]
fn every_settings_key_has_five_nonempty_translations() {
for key in ALL_KEYS {
let (en, de, fr, es, it) = tr(key).unwrap_or_else(|| panic!("{key} resolves"));
assert!(
!en.is_empty()
&& !de.is_empty()
&& !fr.is_empty()
&& !es.is_empty()
&& !it.is_empty(),
"{key}"
);
}
}
#[test]
fn unknown_key_is_not_claimed_by_this_table() {
assert_eq!(tr("settings.does_not_exist"), None);
}
#[test]
fn t_dispatches_settings_keys_through_the_shared_lookup() {
assert_eq!(
t(Lang::De, "settings.save_button"),
"Einstellungen speichern"
);
assert_eq!(
t(Lang::Fr, "settings.err_theme"),
"Le thème doit être 'light' ou 'dark'."
);
assert_eq!(t(Lang::It, "settings.nato_enable_label"), "Abilita NATO");
}
#[test]
fn no_translation_ever_equals_a_protocol_fixed_value_verbatim() {
for key in ALL_KEYS {
let (en, de, fr, es, it) = tr(key).unwrap_or_else(|| panic!("{key} resolves"));
for (lang_code, text) in [("en", en), ("de", de), ("fr", fr), ("es", es), ("it", it)] {
assert!(
!PROTOCOL_FIXED_VALUES.contains(&text),
"{key} ({lang_code}) resolved to the protocol-fixed value {text:?} verbatim"
);
}
}
}
#[test]
fn reset_confirm_never_contains_a_quote_character_in_any_language() {
let texts: [&str; 5] = tr("settings.reset_confirm").expect("key resolves").into();
for text in texts {
assert!(
!text.contains('\''),
"reset_confirm contains an apostrophe: {text:?}"
);
assert!(
!text.contains('"'),
"reset_confirm contains a double quote: {text:?}"
);
}
}
}