مكتبة serde_yaml: العمل مع YAML في Rust
YAML (YAML Ain't Markup Language) هو أحد أشهر صيغ تسلسل البيانات، ويُستخدم على نطاق واسع في ملفات الإعدادات ووصف هياكل البيانات وتبادل المعلومات بين الخدمات. في نظام Rust البيئي، توجد مكتبة ناضجة وعالية الأداء تُسمى serde_yaml، المبنية على إطار العمل القوي serde للتسلسل. في هذا المقال، سنشرح بالتفصيل كيفية تحليل وإنشاء ومعالجة مستندات YAML في Rust.
التثبيت والإعداد
للبدء، أضف التبعيات التالية إلى ملف Cargo.toml الخاص بك:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9"
ستقوم مكتبة serde_yaml تلقائياً بجلب جميع المكونات اللازمة لتحليل وإنشاء YAML.
إلغاء التسلسل الأساسي (YAML → هيكل Rust)
السيناريو الأكثر شيوعاً هو قراءة ملف إعدادات. دعنا نعرف هيكلاً يطابق مستند YAML:
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct Config {
server: ServerConfig,
database: DatabaseConfig,
}
#[derive(Debug, Deserialize)]
struct ServerConfig {
host: String,
port: u16,
workers: Option<u32>,
}
#[derive(Debug, Deserialize)]
struct DatabaseConfig {
url: String,
pool_size: u32,
}
الآن، لنقرأ ملف YAML ونحوله إلى هيكل:
use std::fs;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let yaml_content = fs::read_to_string("config.yaml")?;
let config: Config = serde_yaml::from_str(&yaml_content)?;
println!("الخادم: {}:{}", config.server.host, config.server.port);
println!("قاعدة البيانات: {}", config.database.url);
Ok(())
}
مثال لملف config.yaml:
server:
host: "127.0.0.1"
port: 8080
workers: 4
database:
url: "postgres://user:pass@localhost/db"
pool_size: 10
التسلسل (هيكل Rust → YAML)
العملية العكسية هي إنشاء مستند YAML من البيانات الموجودة في الذاكرة:
use serde::Serialize;
#[derive(Debug, Serialize)]
struct Project {
name: String,
version: String,
dependencies: Vec<Dependency>,
}
#[derive(Debug, Serialize)]
struct Dependency {
name: String,
version: String,
optional: bool,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let project = Project {
name: "my-app".to_string(),
version: "0.1.0".to_string(),
dependencies: vec![
Dependency {
name: "serde".to_string(),
version: "1.0".to_string(),
optional: false,
},
Dependency {
name: "tokio".to_string(),
version: "1.35".to_string(),
optional: true,
},
],
};
let yaml_string = serde_yaml::to_string(&project)?;
println!("{}", yaml_string);
// حفظ في ملف
std::fs::write("project.yaml", &yaml_string)?;
Ok(())
}
التعامل مع مستندات YAML غير المعروفة الهيكل
أحياناً يكون هيكل YAML غير معروف مسبقاً. في هذه الحالات، استخدم serde_yaml::Value:
use serde_yaml::Value;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let yaml_data = "
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app: web
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: web
";
let value: Value = serde_yaml::from_str(yaml_data)?;
// الوصول إلى البيانات المتداخلة
if let Some(ports) = value["spec"]["ports"].as_sequence() {
for port in ports {
if let Some(port_num) = port["port"].as_u64() {
println!("المنفذ: {}", port_num);
}
}
}
// تعديل