Rust
Listing records
Produce a post list with an iterator.
Listing records
Queries on the loaded posts are built with iterator chains. Each query is a predicate closure and they can be combined:
fn yayindakiler<'a>(v: &'a [Yazi], etiket: &str) -> Vec<&'a Yazi> {
v.iter()
.filter(|y| y.yayinda)
.filter(|y| y.etiketler.iter().any(|e| e == etiket))
.collect()
}
The result is a vector of references; the posts aren't copied. Since the return's lifetime is tied to the input slice, 'a is written.
Sorting and summary
A vector of references can be sorted too; by topic with sort_by_key:
let mut liste = yayindakiler(&yazilar, "rust");
liste.sort_by_key(|y| y.konu.clone());
for y in &liste {
println!("{}. {} ({})", y.id, y.konu, y.yazar);
}
sort_by(|a, b| a.konu.cmp(&b.konu)) does the same without cloning.
Exercise Published Rust posts
With the ready veri_seti() data, write the yayindakiler function above. Print the published posts tagged "rust" as id. topic (author).
Show example solution
#[derive(Debug, Clone)]
struct Yazi {
id: u32,
konu: String,
yazar: String,
etiketler: Vec<String>,
yayinda: bool,
}
fn veri_seti() -> Vec<Yazi> {
let y = |id, konu: &str, yazar: &str, et: &[&str], yayinda| Yazi {
id,
konu: konu.to_string(),
yazar: yazar.to_string(),
etiketler: et.iter().map(|e| e.to_string()).collect(),
yayinda,
};
vec![
y(1, "Rust ile başlangıç", "ece", &["rust", "giriş"], true),
y(2, "Sahiplik", "can", &["rust"], false),
y(3, "Web sunucusu", "ece", &["rust", "web"], true),
y(4, "Python notları", "ali", &["python"], true),
]
}
fn yayindakiler<'a>(v: &'a [Yazi], etiket: &str) -> Vec<&'a Yazi> {
v.iter()
.filter(|y| y.yayinda)
.filter(|y| y.etiketler.iter().any(|e| e == etiket))
.collect()
}
fn main() {
let yazilar = veri_seti();
for y in yayindakiler(&yazilar, "rust") {
println!("{}. {} ({})", y.id, y.konu, y.yazar);
}
}
Test yourself
-
Why is a lifetime annotation needed here?
- It isn't needed
- There are two reference parameters; it's unclear which the return depends on
- Vec needs a lifetime
- filter needs a lifetime
Show answer
There are two reference parameters; it's unclear which the return depends on — Elision rules can't determine the return lifetime with two reference parameters; we state explicitly that it depends on v.
-
Is the tag there?
.filter(|y| y.etiketler.iter().____(|e| e == etiket))
Show answer
.filter(|y| y.etiketler.iter().any(|e| e == etiket))
-
Query and result (sample data)
- published + "rust"
- 1, 3
- published + "python"
- 4
- not published
- 2
- "web"
- 3
Next lesson: CLI