Rust
Reading JSON
Read a list of posts with serde_json.
Reading the data
In a real project posts are read from a JSON array in a single line:
let metin = fs::read_to_string("yazilar.json")?;
let yazilar: Vec<Yazi> = serde_json::from_str(&metin)?;
Since there are no external crates in the exercise, we'll use a simpler record format: one record per line, fields separated by |, tags by commas:
1|Rust ile başlangıç|ece|rust,giriş|true
2|Sahiplik|can|rust|false
Parsing a record
The record is split at |; if the number of fields is wrong or a field can't be converted, None is returned. A slice pattern names the five fields in one step:
fn kayittan(s: &str) -> Option<Yazi> {
let alanlar: Vec<&str> = s.split('|').collect();
let [id, konu, yazar, etiket, yayinda] = alanlar[..] else {
return None;
};
Some(Yazi {
id: id.parse().ok()?,
konu: konu.to_string(),
yazar: yazar.to_string(),
etiketler: etiket.split(',').map(String::from).collect(),
yayinda: yayinda.parse().ok()?,
})
}
Exercise Read the records
Write the kayittan function above. Read three lines of data (two valid, the third 3|bozuk kayıt) with lines() and filter_map; print it as 2 kayıt: topic1, topic2.
Show example solution
#[derive(Debug, Clone)]
struct Yazi {
id: u32,
konu: String,
yazar: String,
etiketler: Vec<String>,
yayinda: bool,
}
fn kayittan(s: &str) -> Option<Yazi> {
let alanlar: Vec<&str> = s.split('|').collect();
let [id, konu, yazar, etiket, yayinda] = alanlar[..] else {
return None;
};
Some(Yazi {
id: id.parse().ok()?,
konu: konu.to_string(),
yazar: yazar.to_string(),
etiketler: etiket.split(',').map(String::from).collect(),
yayinda: yayinda.parse().ok()?,
})
}
fn main() {
let veri = "1|Rust ile başlangıç|ece|rust,giriş|true\n2|Sahiplik|can|rust|false\n3|bozuk kayıt";
let yazilar: Vec<Yazi> = veri.lines().filter_map(kayittan).collect();
let konular: Vec<&str> = yazilar.iter().map(|y| y.konu.as_str()).collect();
println!("{} kayıt: {}", yazilar.len(), konular.join(", "));
}
Test yourself
-
What is the risk of silently skipping a broken record?
- The program slows down
- Compile error
- There's no risk
- Data loss goes unnoticed; at least the count should be reported
Show answer
Data loss goes unnoticed; at least the count should be reported — In this lesson we skip broken ones; in the next lesson we'll report each error with its number.
-
Collect the valid ones
let yazilar: Vec<Yazi> = veri.lines().____(kayittan).collect();
Show answer
let yazilar: Vec<Yazi> = veri.lines().filter_map(kayittan).collect();
-
Record and result
- 1|Rust|ece|rust|true
- Some(Yazi)
- 3|bozuk kayıt
- None (fields missing)
- x|a|b|c|true
- None (invalid id)
- 1|a|b|c|evet
- None (invalid bool)
Next lesson: Error handling