العمل مع JSON في Rust: التحليل والتسلسل للمبتدئين

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

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

ابدأ الدورة

مقدمة: لماذا JSON مهم في Rust

\n\n

JSON (JavaScript Object Notation) هو تنسيق خفيف لتبادل البيانات أصبح المعيار الفعلي لواجهات برمجة تطبيقات الويب (API)، وملفات التكوين، والتفاعل بين الخدمات. في Rust، لغة البرمجة النظامية التي تركز على الأمان والأداء، يتم تنفيذ العمل مع JSON من خلال نظام قوي من الكريتات (المكتبات).

\n\n

على الرغم من أن Rust لا يحتوي على دعم مدمج لـ JSON (على عكس JavaScript أو Python)، فإن نظام الأنواع الخاص به وطريقة إدارة الذاكرة تجعل معالجة JSON ليس فقط آمنة، بل سريعة بشكل لا يصدق. في هذه المقالة، سنشرح كيفية تحليل JSON إلى هياكل Rust، وكيفية تسلسل البيانات مرة أخرى إلى JSON، وكيفية تجنب الأخطاء الشائعة للمبتدئين.

\n\n

الأداة الرئيسية للعمل مع JSON في Rust هي الكريت serde (إطار التسلسل/إلغاء التسلسل) إلى جانب serde_json. توفر هذه المكتبات تجريدات بدون تكلفة (zero-cost abstractions) وتدعم هياكل البيانات المتداخلة المعقدة.

\n\n

تثبيت وإعداد التبعيات

\n\n

قبل البدء، قم بإنشاء مشروع Rust جديد وأضف التبعيات الضرورية إلى ملف Cargo.toml:

\n\n
[dependencies]\nserde = { version = "1.0", features = ["derive"] }\nserde_json = "1.0"
\n\n

العلامة features = ["derive"] للكريت serde تسمح باستخدام الماكرو #[derive(Serialize, Deserialize)]، الذي يقوم تلقائيًا بإنشاء الكود لتحويل هياكل البيانات الخاصة بك إلى JSON والعكس. هذه ميزة رئيسية في Rust - تكتب الحد الأدنى من الكود النمطي، ويتولى المترجم العمل الروتيني.

\n\n

بعد إضافة التبعيات، نفذ cargo build لتحميل وتجميع المكتبات.

\n\n

تحليل JSON إلى هياكل Rust (إلغاء التسلسل)

\n\n

إنشاء نموذج البيانات

\n\n

أول شيء يجب فعله هو تحديد هياكل Rust التي تتوافق مع بيانات JSON الخاصة بك. لنفترض أن لدينا JSON يمثل معلومات عن مستخدم:

\n\n
{\n  "name": "أليكسي",\n  "age": 30,\n  "email": "alexey@example.com",\n  "is_active": true\n}
\n\n

لننشئ الهيكل المقابل ونضيف السمات للتسلسل:

\n\n
use serde::{Deserialize, Serialize};\n\n#[derive(Debug, Serialize, Deserialize)]\nstruct User {\n    name: String,\n    age: u32,\n    email: String,\n    is_active: bool,\n}
\n\n

الماكرو #[derive(Debug)] يسمح بطباعة الهيكل في وحدة التحكم لأغراض التصحيح. بدونه، لن تتمكن من استخدام println!("{:?}", user).

\n\n

تحليل سلسلة JSON

\n\n

الآن لنكتب دالة تأخذ سلسلة JSON وتعيد هيكل User:

\n\n
fn parse_user(json_str: &str) -> Result<User, serde_json::Error> {\n    let user: User = serde_json::from_str(json_str)?;\n    Ok(user)\n}\n\nfn main() {\n    let data = r#"\n        {\n            "name": "أليكسي",\n            "age": 30,\n            "email": "alexey@example.com",\n            "is_active": true\n        }\n    "#;\n\n    match parse_user(data) {\n        Ok(user) => println!("المستخدم: {:?}", user),\n        Err(e) => eprintln!("خطأ في التحليل: {}", e),\n    }\n}
\n\n

النقطة الأساسية: serde_json::from_str يقوم تلقائيًا بمطابقة حقول JSON مع حقول الهيكل. إذا كانت أسماء الحقول في JSON تختلف عن الأسماء في Rust (على سبيل المثال، JSON يستخدم snake_case بينما Rust يستخدم camelCase)، يمكن استخدام السمة #[serde(rename = "اسم_الحقل")].

\n\n

معالجة الهياكل المتداخلة

\n\n

غالبًا ما يحتوي JSON على كائنات متداخلة. لننظر إلى مثال مع عنوان المستخدم:

\n\n
{\n  "name": "أليكسي",\n  "address": {\n    "city": "موسكو",\n    "street": "تفيرسكايا",\n    "zip": "101000"\n  }\n}
\n\n

لننشئ الهياكل المتداخلة:

\n\n
#[derive(Debug, Serialize, Deserialize                

المدونات

توصيات الكتب