الصباح: كود، قهوة ومترجم
\n\nفي عالم البرمجة النظامية، تحتل Rust مكانة خاصة. فهي تجمع بين سرعة C++ وأمان الذاكرة الذي يضمنه المترجم على مستوى الأنواع. ولكن كيف يبدو يوم العمل الفعلي لمطور يكتب بلغة Rust؟ انسَ الصور النمطية عن "مبرمجي الأنظمة المملين" - اليوم سنحلل يومًا حقيقيًا من حياة مهندس Rust. بدون تجميل، مع أجزاء كود حقيقية ومشاكل حية.
\n\nتخيل: الساعة 9:00 صباحًا. تفتح الكمبيوتر المحمول، تشغل الطرفية وترى رسالة من CI: "Build failed". تتنهد، تفتح cargo check وتغوص في عالم borrow checker. مرحبًا بك في يوم مطور Rust.
صباح قياسي: مراجعة الكود والتذاكر
\nأول شيء - فحص طلبات السحب. في فرق Rust، مراجعة الكود مهمة بشكل خاص لأن المترجم يلتقط الكثير من الأخطاء، لكن المنطق والهندسة يفحصهما البشر. تنظر إلى PR زميلك الذي يضيف وحدة جديدة لمعالجة الإعدادات.
\n\n// config.rs — تحليل الإعدادات\nuse serde::Deserialize;\nuse std::path::Path;\n\n#[derive(Debug, Deserialize)]\nstruct AppConfig {\n host: String,\n port: u16,\n max_connections: u32,\n db_url: String,\n}\n\nfn load_config(path: impl AsRef<Path>) -> Result<AppConfig, ConfigError> {\n let content = std::fs::read_to_string(path.as_ref())?;\n let config: AppConfig = toml::from_str(&content)?;\n Ok(config)\n}\n\nتلاحظ: لا يوجد تحقق من السلاسل الفارغة. تضيف تعليقًا: "ماذا لو كان host فارغًا؟ ربما نضيف التحقق عبر validator؟" بعد 15 دقيقة يرد الزميل: "أوافق، أضفت #[validate]". يبدأ اليوم بشكل منتج.
الجزء الرئيسي: الغوص في الكود
\n\n10:00 — العمل مع عدم التزامن و tokio
\nتنتقل إلى مهمتك: إعادة كتابة خادم HTTP الذي يعالج webhooks. الكود القديم مكتوب على خيوط حظر، وهو بطيء. أداتك هي tokio و async/await. Rust مناسبة تمامًا للأنظمة عالية التحميل، وأنت تعرف ذلك.
\n\nتكتب معالجًا جديدًا:
\n\nuse axum::{\n routing::post,\n Router,\n Json,\n};\nuse serde_json::Value;\n\nasync fn handle_webhook(Json(payload): Json<Value>) -> String {\n // التحقق، المعالجة، الكتابة في قاعدة البيانات\n println!("تم استلام webhook: {:?}", payload);\n tokio::time::sleep(std::time::Duration::from_millis(100)).await;\n "OK".to_string()\n}\n\n#[tokio::main]\nasync fn main() {\n let app = Router::new()\n .route("/webhook", post(handle_webhook));\n\n axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())\n .serve(app.into_make_service())\n .await\n .unwrap();\n}\n\nتشغل cargo run - لا توجد أخطاء. أثبتت Rust موثوقيتها مرة أخرى. لكن هذه مجرد البداية.
11:30 — المعركة مع borrow checker
\nفجأة يأتي تقرير خطأ: "ذعر عند معالجة قائمة المستخدمين". تفتح الكود وترى المشكلة: المؤشر &mut يُستخدم في عدة أماكن. Rust لن تسمح لك بإطلاق النار على قدمك، لكنها أحيانًا تتقاتل معك على حق الملكية.
هذا هو المقطع الإشكالي:
\n\nfn process_users(users: &mut Vec<User>) {\n let admin = users.iter_mut().find(|u| u.role == Role::Admin).unwrap();\n admin.do_task(); // استعارة mutable\n // وهنا نريد استخدام users مرة أخرى\n let count = users.len(); // خطأ! users مستعارة بالفعل\n}\n\nتقوم بالإصلاح عن طريق فصل المنطق:
\n\nfn process_users(users: &mut Vec<User>) {\n // أولاً نجد الفهرس، ثم نعمل\n if let Some(admin_idx) = users.iter().position(|u| u.role == Role::Admin) {\n let admin = &mut users[admin_idx];\n admin.do_task();\n }\n // الآن يمكننا استخدام