التدويل (i18n) في Rust: أفضل المكتبات والممارسات

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

التدويل (i18n) في Rust: نظرة عامة على المكتبات والأدوات

\n\n

التدويل (اختصاراً i18n - من 18 حرفاً بين 'i' و 'n') هو عملية تصميم التطبيق بحيث يمكن تكييفه مع لغات ومعايير إقليمية مختلفة دون تغيير الكود المصدري. في نظام Rust البيئي، توجد عدة مكتبات ناضجة لتنفيذ i18n. في هذه المقالة، سنستعرض ثلاثة أساليب رئيسية: الكلاسيكي gettext، والمكتبة الموجهة بالماكرو rust-i18n، والحديث fluent-rs من Mozilla.

\n\n

1. مكتبة gettext (crate gettext-rs)

\n

gettext هو المعيار الفعلي لتوطين أنظمة Unix. توفر الواجهة البرمجية لـ Rust gettext-rs وصولاً كاملاً إلى دوال GNU gettext.

\n\n

التثبيت

\n
[dependencies]\ngettext-rs = "0.7"
\n\n

مثال على الاستخدام

\n
use gettextrs::*;\nuse std::env;\n\nfn main() {\n    // تعيين الإعدادات المحلية والنطاق\n    setlocale(LocaleCategory::LcAll, "ru_RU.UTF-8");\n    bindtextdomain("myapp", "/usr/share/locale").unwrap();\n    textdomain("myapp");\n\n    // ترجمة سلسلة نصية\n    println!("{}", gettext("Hello, world!"));\n    \n    // صيغ الجمع (العدد الجمعي)\n    let n = 5;\n    println!("{}", ngettext("{} apple", "{} apples", n, n));\n}
\n\n

المزايا: النضج، دعم صيغ الجمع، الترجمات السياقية (pgettext)، التكامل مع Poedit و Transifex.
\nالعيوب: يتطلب تثبيت gettext على مستوى النظام، دعم غير مثالي لـ Unicode على Windows.

\n\n

2. مكتبة rust-i18n

\n

تنفيذ خالص بلغة Rust بدون تبعيات خارجية. تستخدم ملفات YAML لتخزين الترجمات والماكرو لاستخراج السلاسل النصية.

\n\n

التثبيت

\n
[dependencies]\nrust-i18n = "3.0"
\n\n

هيكل المشروع

\n
locales/\n├── en.yml\n└── ru.yml
\n\n

مثال locales/ru.yml:

\n
hello: "مرحباً بالعالم!"\napples: \n  zero: "لا يوجد تفاح"\n  one: "{} تفاحة"\n  few: "{} تفاحات"\n  many: "{} تفاح"
\n\n

الاستخدام في الكود

\n
use rust_i18n::t;\n\nrust_i18n::i18n!("locales");\n\nfn main() {\n    // ترجمة بسيطة\n    println!("{}", t!("hello"));\n\n    // صيغ الجمع مع مراعاة قواعد اللغة العربية\n    let n = 3;\n    println!("{}", t!("apples", count = n, n));\n}
\n\n

المزايا: البساطة، التحديد التلقائي للإعدادات المحلية، دعم العناصر النائبة وصيغ الجمع للغات المعقدة (الروسية، العربية).
\nالعيوب: أقل مرونة من gettext، لا يوجد دعم للسياقات.

\n\n

3. مكتبة fluent-rs

\n

طورتها Mozilla لمتصفح Firefox. تستخدم بناء جملة خاص بها FTL (قائمة ترجمة Fluent).

\n\n

التثبيت

\n
[dependencies]\nfluent = "0.16"\nfluent-bundle = "0.15"\nfluent-resmgr = "0.4"
\n\n

مثال على ملف FTL (locales/ar/main.ftl)

\n
hello = مرحباً بالعالم!\napples = \n    { $count ->\n        [0] لا يوجد تفاح\n        [one] { $count } تفاحة\n        [two] { $count } تفاحتان\n       *[many] { $count } تفاحة\n    }
\n\n

الاستخدام في Rust

\n
use fluent_bundle::{FluentBundle, FluentResource};\nuse fluent_resmgr::ResourceManager;\nuse unic_langid::langid;\n\nfn main() {\n    let langid = langid!("ar");\n    let res_mgr = ResourceManager::new("./locales/".into());\n    \n    let mut bundle = FluentBundle::new(&[langid]);\n    let ftl_string = res_mgr.load("ar/main.ftl").unwrap();\n    let resource = FluentResource::try_new(ftl_string).unwrap();\n    bundle.add_resource(resource).unwrap();\n\n    let mut errors = vec![];\n    let msg = bundle.format_pattern(\n        bundle.get_message("hello").unwrap().value().unwrap(),\n        None,\n        &mut errors\n    );\n    println!("{}", msg);\n\n    // صيغ الجمع\n    let mut args = fluent_bundle::FluentArgs::new();\n                    

توصيات