Warum Ihre Rust-Anwendung Internationalisierung braucht (und wie Sie es nicht vermasseln)
\n\nSie haben den perfekten Parser in Rust geschrieben. Er fliegt schneller als der Blitz und verbraucht weniger Speicher als eine bescheidene Kohlmeise. Aber es gibt ein Problem: Ihr Text wird nur auf Englisch ausgegeben. Und Benutzer aus Tokio, Berlin und Sankt Petersburg möchten die Oberfläche in ihrer Muttersprache sehen.
\n\nInternationalisierung (i18n) ist nicht nur das "Übersetzen von Schaltflächen". Es ist eine architektonische Entscheidung, die Ihren Code in einen eleganten Konstrukteur oder eine höllische Ansammlung von if-else-Anweisungen verwandeln kann. In diesem Artikel werden wir analysieren, wie man Internationalisierung in Rust richtig macht: ohne Schmerzen, mit Beispielen und mit Respekt für das Gehirn des zukünftigen Entwicklers (Ihres).
\n\nWir werden über zwei leistungsstarke Ansätze sprechen: die fluent-Bibliothek (Empfehlung von Mozilla) und das klassische rust-i18n, das auf gettext basiert. Am Ende des Artikels werden Sie in der Lage sein, in 15 Minuten Unterstützung für Russisch, Englisch und jede andere Sprache zu Ihrem Tool hinzuzufügen.
Schlachtplan: Was sind i18n und l10n in der Rust-Welt
\n\nBevor wir in den Code eintauchen, lassen Sie uns die Begriffe klären:
\n- \n
- Internationalisierung (i18n) — Vorbereiten des Codes für die Übersetzung. Sie extrahieren alle Zeichenfolgen in separate Dateien und bringen dem Programm bei, das erforderliche Gebietsschema zu laden. \n
- Lokalisierung (l10n) — die Übersetzung selbst. Erstellen von Dateien für jede Sprache. \n
- Gebietsschema (Locale) — eine Kombination aus Sprache und Region (z. B.
ru-RU,en-US,de-DE). \n
In Rust gibt es mehrere Wege. Wir werden uns die beiden beliebtesten ansehen:
\n- \n
- Fluent — ein modernes System von Mozilla. Leistungsstark, flexibel, mit Unterstützung für Pluralbildung und Kontext. \n
- rust-i18n — Makros, inspiriert von Ruby on Rails. Einfacher, aber weniger flexibel. \n
Die Wahl hängt von der Aufgabe ab. Für CLI-Dienstprogramme ist rust-i18n ausreichend. Für Webanwendungen oder komplexe GUIs (z. B. auf Tauri) ist es besser, Fluent zu verwenden.
Methode #1: Rust-Internationalisierung mit Fluent (Professioneller Ansatz)
\n\nInstallieren und Konfigurieren von Fluent
\n\nLassen Sie uns ein neues Projekt erstellen und Abhängigkeiten hinzufügen:
\n\ncargo new i18n_demo\ncd i18n_demo\ncargo add fluent fluent-bundle fluent-langtag unic-langid\n\n\nDie Dateistruktur wird wie folgt aussehen:
\n\nprojekt/\n├── Cargo.toml\n├── locales/\n│ ├── ru/\n│ │ └── main.ftl\n│ └── en/\n│ └── main.ftl\n└── src/\n └── main.rs\n\n\nErstellen von Lokalisierungsdateien (FTL)
\n\nFluent verwendet das FTL-Format (Fluent Translation List). Es ist sauber und leistungsstark:
\n\nlocales/en/main.ftl:
\ngreeting = Hello, { $name }!\ngoodbye = Goodbye\napples = { $count ->\n [one] { $count } apple\n [few] { $count } apples\n *[other] { $count } apples\n}\n\n\nlocales/ru/main.ftl:
\ngreeting = Привет, { $name }!\ngoodbye = До свидания\napples = { $count ->\n [one] { $count } яблоко\n [few] { $count } яблока\n [many] { $count } яблок\n *[other] { $count } яблок\n}\n\n\nBeachten Sie die Pluralbildung. Im Russischen gibt es vier Formen (eins, zwei-vier, fünf-zwanzig, der Rest), während es im Englischen zwei gibt (eins, der Rest). Fluent verarbeitet dies automatisch.
\n\nSchreiben von Rust-Code zum Laden von Gebietsschemata
\n\nJetzt der interessante Teil — der Code, der die gewünschte Sprache basierend auf dem System des Benutzers auswählt:
\n\nuse fluent_bundle::{FluentBundle, FluentResource};\nuse unic_langid::LanguageIdentifier;\nuse std::fs;\nuse std::path::Path;\n\nfn load_locale(locale: &str) -> FluentBundle<FluentResource> {\n let langid: LanguageIdentifier = locale.parse().expect("Invalid locale");\n let mut bundle = FluentBundle::new(vec![langid]);\n\n let file_path = format!("locales/{}/main.ftl", locale);\n let source = fs::read_to_string(&file_path)\n .expect(&fo