العمل مع YAML في Rust: مكتبة serde_yaml

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

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

ابدأ الدورة

مقدمة في العمل مع YAML على Rust

YAML (YAML Ain't Markup Language) — أحد أكثر التنسيقات شيوعًا لملفات الإعدادات بفضل سهولة قراءته ومرونته. في نظام Rust البيئي، يُستخدم الكريت serde_yaml للعمل مع YAML، وهو مبني على منصة التسلسل القوية Serde. تتيح هذه المكتبة تحويل هياكل Rust إلى YAML والعكس بسهولة.



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

أضف التبعيات إلى ملف Cargo.toml الخاص بك:

[dependencies]serde = { version = "1.0", features = ["derive"] }serde_yaml = "0.9"


بعد تحديث المشروع، نفّذ cargo build. المكتبة جاهزة للاستخدام.



إلغاء التسلسل الأساسي لـ YAML في Rust

لننظر إلى مثال بسيط — قراءة سلسلة YAML وتحويلها إلى هيكل Rust.



الخطوة 1: تعريف الهيكل

use serde::Deserialize;

#[derive(Debug, Deserialize)]struct Config { host: String, port: u16, debug: bool,}


الخطوة 2: تحليل YAML

use serde_yaml;

fn main() -> Result<(), serde_yaml::Error> { let yaml_str = r#" host: "127.0.0.1" port: 8080 debug: true "#;

let config: Config = serde_yaml::from_str(yaml_str)?; println!("{:?}", config); Ok(())}


المخرجات: Config { host: "127.0.0.1", port: 8080, debug: true }



تسلسل هياكل Rust إلى YAML

العملية العكسية — تحويل بيانات Rust إلى سلسلة YAML:



use serde::Serialize;

#[derive(Debug, Serialize)]struct Server { name: String, ip: String, ports: Vec<u16>,}

fn main() -> Result<(), serde_yaml::Error> { let server = Server { name: "web-server".into(), ip: "10.0.0.1".into(), ports: vec![80, 443, 22], };

let yaml = serde_yaml::to_string(&server)?; println!("{}", yaml); Ok(())}


النتيجة:

---name: web-serverip: 10.0.0.1ports:  - 80  - 443  - 22


العمل مع الهياكل المتداخلة والوسوم

يدعم YAML التسلسلات الهرمية المعقدة. في Rust، يُعكس ذلك على هياكل وتعدادات متداخلة:



use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]struct Database { #[serde(rename = "db")] database: DbConfig, pool_size: u32,}

#[derive(Debug, Serialize, Deserialize)]struct DbConfig { host: String, port: u16, user: String, password: String,}

fn main() -> Result<(), serde_yaml::Error> { let yaml = r#" db: host: "localhost" port: 5432 user: "admin" password: "secret" pool_size: 10 "#;

let db: Database = serde_yaml::from_str(yaml)?; println!("{:#?}", db); Ok(())}


لاحظ السمة #[serde(rename = "db")] — فهي تسمح بمطابقة حقل Rust مع اسم آخر في YAML.



معالجة الأخطاء والحقول الاختيارية

غالبًا ما تحتوي ملفات YAML الحقيقية على معاملات اختيارية. استخدم Option<T>:



#[derive(Debug, Deserialize)]struct AppConfig {    name: String,    version: String,    #[serde(default)]    features: Vec<String>,    #[serde(default = "default_timeout")]    timeout: u64,}

fn default_timeout() -> u64 { 30}


السمة #[serde(default)] تُعيّن قيمة افتراضية (مصفوفة فارغة لـ Vec، None لـ Option). يمكن تحديد دالة مولّدة، كما في مثال timeout.



قراءة YAML من ملف

عمليًا، تُخزّن الإعدادات في ملفات. القراءة بسيطة:



use std::fs;use serde_yaml;

fn main() -> Result<(), Box<dyn std::error::Error>

توصيات