تسلسل الكائنات في Rust: نظرة عامة على المكتبات والأدوات
\n\nالتسلسل هو أحد العمليات الأساسية في تطوير البرمجيات. فهو يسمح بتحويل هياكل البيانات المعقدة (الكائنات، الهياكل، التعدادات) إلى تنسيق متسلسل، مناسب للتخزين على القرص أو النقل عبر الشبكة. العملية العكسية - إلغاء التسلسل - تستعيد الكائنات الأصلية من هذا التنسيق. في لغة Rust، يتم حل هذه المهمة بواسطة نظام بيئي، تحتل فيه مكتبة Serde (Serialization/Deserialization) مكانة مركزية.
\n\nفي هذه المقالة، سنشرح بالتفصيل كيفية عمل التسلسل في Rust، وما هي المكتبات الموجودة له، وكيفية استخدامها عمليًا.
\n\nلماذا Serde؟
\n\nSerde ليست مجرد مكتبة، بل هي إطار عمل للتسلسل وإلغاء التسلسل. ميزتها الرئيسية هي التقسيم إلى جزأين:
\n\n- \n
- نموذج بيانات Serde - النواة التي تحدد كيفية تحويل أنواع بيانات Rust إلى تمثيل وسيط. \n
- محولات التنسيقات - صناديق (crates) منفصلة تعمل مع تنسيقات محددة (JSON، YAML، TOML، Bincode، MessagePack وغيرها). \n
يسمح هذا النهج باستخدام نفس الكود للعمل مع تنسيقات مختلفة، مع تغيير سطر واحد فقط في Cargo.toml.
الإعداد الأساسي والتوصيل
\n\nللبدء، أضف التبعيات التالية إلى Cargo.toml:
[dependencies]\nserde = { version = "1.0", features = ["derive"] }\nserde_json = "1.0"\n\nالميزة الرئيسية هي استخدام الخاصية #[derive(Serialize, Deserialize)]. فهي تنشئ تلقائيًا الكود لتحويل الهياكل الخاصة بك:
use serde::{Serialize, Deserialize};\n\n#[derive(Debug, Serialize, Deserialize)]\nstruct User {\n id: u64,\n name: String,\n email: String,\n is_active: bool,\n}\n\nfn main() {\n let user = User {\n id: 42,\n name: "أليكسي".to_string(),\n email: "alex@example.com".to_string(),\n is_active: true,\n };\n\n // التسلسل إلى JSON\n let json = serde_json::to_string_pretty(&user).unwrap();\n println!("JSON:\\n{}", json);\n\n // إلغاء التسلسل مرة أخرى\n let deserialized: User = serde_json::from_str(&json).unwrap();\n println!("تم الاستعادة: {:?}", deserialized);\n}\n\nالعمل مع تنسيقات مختلفة
\n\nيدعم Serde عشرات التنسيقات. دعنا نلقي نظرة على الأكثر شيوعًا:
\n\nJSON (serde_json)
\nالتنسيق الأكثر انتشارًا لواجهات برمجة تطبيقات الويب. قابل للقراءة البشرية، لكنه يستهلك مساحة كبيرة.
\n\n// التسلسل إلى سلسلة نصية\nlet json_str = serde_json::to_string(&data)?;\n\n// التسلسل إلى تيار (ملف)\nlet file = std::fs::File::create("data.json")?;\nlet writer = std::io::BufWriter::new(file);\nserde_json::to_writer(writer, &data)?;\n\n// القراءة من ملف\nlet file = std::fs::File::open("data.json")?;\nlet reader = std::io::BufReader::new(file);\nlet data: MyStruct = serde_json::from_reader(reader)?;\n\nBincode (bincode)
\nتنسيق ثنائي - مضغوط وسريع. مثالي للتخزين الداخلي أو النقل بين الخدمات المكتوبة بلغة Rust.
\n\n// Cargo.toml: bincode = "1.3"\n\nlet encoded: Vec<u8> = bincode::serialize(&data)?;\nlet decoded: MyStruct = bincode::deserialize(&encoded)?;\n\nYAML و TOML (serde_yaml, toml)
\nيُستخدمان لملفات التكوين. قابلان للقراءة البشرية، ويدعمان التعليقات (YAML).
\n\n// YAML\nlet yaml = serde_yaml::to_string(&data)?;\nlet data: MyStruct = serde_yaml::from_str(&yaml)?;\n\n// TOML (شائع في النظام البيئي لـ Rust)\nlet toml = toml::to_string(&data)?;\nlet data: MyStruct = toml::from_str(&toml)?;\n\nإمكانيات متقدمة: خصائص Serde
\n\nيوفر Serde خصائص قوية للتحكم الدقيق في عملية التسلسل:
\n\n#[derive(Serialize, Deser