Rust
Özet - Serde
serde_json ve derive'ı birleştirerek bir config okuyucu yazarsın.
Serde özeti
#[derive(Serialize, Deserialize)] veri yapısını biçimden bağımsız tanımlar; biçimi serde_json gibi bir crate sağlar (to_string, from_str). Adlar rename/rename_all ile eşlenir. Eksik alanlar Option ya da #[serde(default)] ile tolere edilir; skip_serializing_if boş alanları atlar. Okuma her zaman Result döndürür ve hata mesajı eksik ya da hatalı alanı söyler.
Gidiş dönüş
Bir ayar türünü yazıp aynı metinden geri okuyan iki fonksiyon:
#[derive(Debug, PartialEq)]
struct Ayar {
port: u16,
hata_ayikla: bool,
}
impl Ayar {
fn json(&self) -> String {
format!("{{\"port\":{},\"hata_ayikla\":{}}}", self.port, self.hata_ayikla)
}
fn oku(s: &str) -> Result<Ayar, String> { /* anahtar anahtar ayrıştır */ }
}
Okuyucu her anahtarı türüne göre çevirmeli ve bilinmeyen anahtarda anlaşılır bir hata vermelidir.
Uygulama Ayar gidiş dönüş
Yukarıdaki Ayar türü için json ve oku metotlarını yaz (oku: süslü parantezleri at, virgülden böl, split_once(':'), anahtara göre parse). Ayar { port: 8080, hata_ayikla: false } için JSON'u yazdır, sonra onu geri okuyup {:?} ile yazdır.
Örnek çözümü göster
#[derive(Debug, PartialEq)]
struct Ayar {
port: u16,
hata_ayikla: bool,
}
impl Ayar {
fn json(&self) -> String {
format!("{{\"port\":{},\"hata_ayikla\":{}}}", self.port, self.hata_ayikla)
}
fn oku(s: &str) -> Result<Ayar, String> {
let mut port = None;
let mut hata_ayikla = None;
for cift in s.trim().trim_start_matches('{').trim_end_matches('}').split(',') {
let (a, d) = cift.split_once(':').ok_or("geçersiz çift")?;
let deger = d.trim();
match a.trim().trim_matches('"') {
"port" => port = Some(deger.parse().map_err(|_| "geçersiz port")?),
"hata_ayikla" => hata_ayikla = Some(deger.parse().map_err(|_| "geçersiz bool")?),
k => return Err(format!("bilinmeyen anahtar: {k}")),
}
}
Ok(Ayar {
port: port.ok_or("port eksik")?,
hata_ayikla: hata_ayikla.ok_or("hata_ayikla eksik")?,
})
}
}
fn main() {
let a = Ayar { port: 8080, hata_ayikla: false };
let metin = a.json();
println!("{}", metin);
println!("{:?}", Ayar::oku(&metin).unwrap());
}
Kendini test et
-
Bir yapılandırmayı yazıp geri okuduğunda aynı değeri almak (round-trip) neden önemli bir testtir?
- Yazma ve okuma kodlarının birbiriyle uyumlu olduğunu kanıtlar
- Performansı ölçer
- Gerekli değildir
- Dosya boyutunu küçültür
Cevabı göster
Yazma ve okuma kodlarının birbiriyle uyumlu olduğunu kanıtlar — Elle yazılmış serileştirmede özellikle değerlidir; derive kullanırken bile rename gibi özniteliklerin doğru çalıştığını gösterir.
-
Mantıksal değeri oku
"hata_ayikla" => hata_ayikla = deger.____().map_err(|_| "geçersiz bool")?,
Cevabı göster
"hata_ayikla" => hata_ayikla = deger.parse().map_err(|_| "geçersiz bool")?,
-
Grubun özeti
- to_string
- Yazma
- from_str
- Okuma
- rename_all
- Ad kuralı
- skip_serializing_if
- Boşu atla
Sıradaki ders: Model iskeleti