مستودع واحد مع Rust: تنظيم الكود للمبتدئين

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

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

ابدأ الدورة

مقدمة: لماذا تحتاج إلى مستودع واحد في Rust؟



عندما تبدأ في تعلم Rust، أول ما ستواجهه هو مشروع فردي تم إنشاؤه عبر cargo new. ولكن ماذا تفعل عندما يتوسع مشروعك: تظهر مكتبات مشتركة، عدة ملفات قابلة للتنفيذ (مثل الخادم والعميل) أو تريد نقل الكود المتكرر إلى حزمة منفصلة؟



هنا يأتي دور المستودع الواحد (monorepo) - وهو نهج يتم فيه تخزين كود عدة مشاريع مترابطة (مكتبات وملفات قابلة للتنفيذ) في مستودع واحد. يوفر Rust حلاً مدمجًا لذلك - Cargo Workspaces (مساحات العمل).



في هذه المقالة، سنشرح كيفية تنظيم مستودع واحد في Rust من الصفر: بدءًا من هيكل المجلدات وصولاً إلى الأمثلة العملية. ستتعلم كيفية تقسيم الكود بشكل صحيح إلى وحدات، وربط التبعيات المحلية، وإدارة عملية البناء.



1. ما هو Cargo Workspace وكيفية إنشائه؟



مساحة العمل (workspace) هي مجموعة من الكريتات (crates) التي تستخدم نفس ملف Cargo.lock ودليلاً مشتركًا target. هذا يسمح بتجنب تعارضات إصدارات التبعيات ويسرّع عملية التجميع.



إنشاء هيكل المستودع الواحد



لننشئ مستودعًا واحدًا بسيطًا مع كريتين: مكتبة utils وملف قابل للتنفيذ app.



mkdir my_monorepocd my_monorepocargo new utils --libcargo new app


الآن لننشئ ملف الجذر Cargo.toml الذي سيعلن عن مساحة العمل:



[workspace]members = [    "utils",    "app",]


هام: تأكد من أن ملفات utils/Cargo.toml و app/Cargo.toml لا تحتوي على قسم [package] مع حقل workspace - فهو غير مطلوب. سيفهم Cargo تلقائيًا أنها جزء من مساحة العمل.



هيكل المشروع



بعد الإنشاء، ستحصل على الهيكل التالي:



my_monorepo/├── Cargo.toml          # مساحة العمل الجذرية├── utils/│   ├── Cargo.toml│   └── src/│       └── lib.rs└── app/    ├── Cargo.toml    └── src/        └── main.rs


2. تنظيم الكود: المكتبات والوحدات



الآن لنضف كودًا إلى مكتبة utils. لنفترض أننا نريد إنشاء دوال مشتركة للعمل مع الأرقام والسلاسل النصية.



كود المكتبة (utils/src/lib.rs)



pub mod math;pub mod strings;


لننشئ ملفات الوحدات:



// utils/src/math.rspub fn add(a: i32, b: i32) -> i32 {    a + b}

pub fn multiply(a: i32, b: i32) -> i32 { a * b}


// utils/src/strings.rspub fn greet(name: &str) -> String {    format!("مرحبًا، {}!", name)}

pub fn to_uppercase(text: &str) -> String { text.to_uppercase()}


ربط المكتبة في الملف القابل للتنفيذ



في ملف app/Cargo.toml، نحدد التبعية للكريت المحلي:



[package]name = "app"version = "0.1.0"edition = "2021"

[dependencies]utils = { path = "../utils" }


الآن في app/src/main.rs يمكننا استخدام الدوال من utils:



use utils::math;use utils::strings;

fn main() { let sum = math::add(5, 10); println!("5 + 10 = {}", sum);

let greeting = strings::greet("العالم"); println!("{}", greeting);

let upper = strings::to_uppercase("rust rocks"); println!("{}", upper);}


قم بتشغيل المشروع من جذر المستودع الواحد باستخدام الأمر:



cargo run -p app


سترى الإخراج:



5 + 10 = 15مرحبًا، العالم!RUST ROCKS


3. تنظيم متقدم: عدة ملفات قابلة للتنفيذ



غالبًا ما يكون من الضروري في المستودع الواحد وجود عدة

المدونات

توصيات الكتب