Custom ordering in Rust
Implementing Ord decides how your type sorts everywhere it is compared.
#[derive(Debug, PartialEq, Eq)]
struct Step {
stars: u8,
title: String,
}
impl Ord for Step {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
other
.stars
.cmp(&self.stars)
.then_with(|| self.title.cmp(&other.title))
}
}
impl PartialOrd for Step {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
fn main() {
let mut steps = vec![
Step { stars: 1, title: "Slices".to_string() },
Step { stars: 3, title: "Traits".to_string() },
Step { stars: 3, title: "Errors".to_string() },
];
steps.sort();
for s in &steps {
println!("{} {}", s.stars, s.title);
}
}
How it works
- Deriving
PartialOrdcompares fields in declaration order. - A hand-written
Ordpicks the rule you want. sortthen needs no comparator at the call site.
Keywords and builtins used here
OptionOrdPartialOrdSelfSomeStepStringcmpfnforimplinletmainmutpartial_cmpselfstdstructu8
The run, in numbers
- Lines
- 32
- Characters to type
- 602
- Tokens
- 198
- Three-star pace
- 105 tpm
At the three-star pace of 105 tokens a minute, this run takes about 113 seconds.
Step 4 of 4 in Standard traits, step 11 of 19 in Traits & generics.