Rust'ta veri serileştirme ve deserialization görevleri sık karşılaşılan durumlar olup, özellikle web hizmetleri, veri tabanları veya bileşenler arasındaki mesaj alışverişi ile entegrasyonda önemlidir. Bu alandaki en popüler kütüphane serde'dir, bu da Rust'ta serileştirme için fiili standart haline gelmiştir.
Konuya Giriş
Rust geliştiricileri, esnek ve verimli bir serileştirme çözümüne ihtiyaç duydu. Başlangıçta özel çözümler mevcuttu, ancak serde, derive makroları ile kolay entegrasyon ve çeşitli formatlar (JSON, CBOR, BSON, TOML, YAML vb.) desteği sunmasıyla öne çıktı.
Sorun
Rust yapılarının veri alışverişi formatlarına (örneğin JSON) doğru bir şekilde dönüştürülmesini sağlamak ve tam tipleme güvenliğini koruyarak "sessiz hatalar" oluşturulmaması gerekmektedir. Sorunlar çoğunlukla veri yapısındaki uyumsuzluk veya desteklenmeyen türlerin serileştirilmesi girişiminden kaynaklanmaktadır.
Çözüm
Yapıların serileştirilmesi için Serialize ve Deserialize trait'lerini uygulamak gerekmektedir, genellikle #[derive(Serialize, Deserialize)] ile yapılır. Standart olmayan durumlar için bu trait'leri elle uygulamak veya serileştirme şemasını yönetmek için öznitelikler kullanmak mümkündür.
Kod Örneği:
use serde::{Serialize, Deserialize}; #[derive(Serialize, Deserialize, Debug)] struct Person { name: String, age: u8, } fn main() { let data = Person { name: "Bob".into(), age: 32 }; let json = serde_json::to_string(&data).unwrap(); println!("{}", json); let obj: Person = serde_json::from_str(&json).unwrap(); println!("{:?}", obj); }
Ana Özellikler:
Option alanlarını veya varsayılan değerlere sahip alanları nasıl serileştirip/deserialize edebiliriz?
Varsayılan bir değer belirtmek için #[serde(default)] kullanabilir veya None değerlerini serileştirmemek için #[serde(skip_serializing_if = "Option::is_none")] kullanabilirsiniz.
Kod Örneği:
#[derive(Serialize, Deserialize)] struct Config { #[serde(default)] timeout: Option<u32>, }
Özel alanlara veya hesaplanan değerlere (örneğin fn get_hash()) sahip yapıların serileştirilmesi mümkün mü?
Evet, ancak böyle alanlar serileştirilmeyecekse #[serde(skip)] ile işaretlenmeli veya hesaplanan değerleri serileştirmek için Serialize/Deserialize'ı manuel olarak uygulamalısınız.
Eğer Rust'taki yapı JSON nesnesiyle (bir alan eksikse veya yeni bir alan varsa) eşleşmiyorsa ne olur?
Varsayılan olarak serde, JSON'daki gereksiz alanları göz ardı eder (katı mod açık değilse) ve yapıdaki zorunlu alanlar eksikse hata verir (#[serde(default)] belirtilmemişse).
Dış bir JSON ile gereksiz ve eksik alanlar gelirken, yapı #[serde(default)] kullanmıyorsa,
Artılar:
Eksiler:
#[serde(default)] ve #[serde(skip_serializing_if)] kullanılıyor, tüm alanlar doğrulanıyor, gereksiz olanlar göz ardı ediliyor.
Artılar:
Eksiler: