I implemented Ord::cmp below, and I feel there should be an easier way. Is there? The reason I'm not deriving Ord is because the docs say sorting is lexicographic, which would mean 10 comes before 9, but maybe I'm misunderstanding the docs? Thanks!
9 < 10 for derive(Ord). "Lexicographic" here doesn't mean elements are converted to strings, it means struct elements are compared as a sequence of symbols, in your case 4 symbols, the first one being the most significant, the second one second-most significant, etc.
In other words, the derived Ord is exactly what you implemented.
While the derive is what you want in this case, for the future you can solve the nesting with something like this:
impl Ord for Variant {
fn cmp(&self, other: &Self) -> Ordering {
use Ordering::*;
if let e @ (Less | Greater) = self.chrom.cmp(&other.chrom) {
return e;
}
if let e @ (Less | Greater) = self.pos.cmp(&other.pos) {
return e;
}
if let e @ (Less | Greater) = self.ref_allele.cmp(&other.ref_allele) {
return e;
}
if let e @ (Less | Greater) = self.alt_allele.cmp(&other.alt_allele) {
return e;
}
Equal
}
}
It's perhaps best to understand that for strings, characters from A-Z are sorted as less than any character from a-z. So "alice", "Bert", "Clare" will after sorting be in order "Bert", "Clare", "alice".
Rust's built-in ordering for strings is not really useful except for it's utility in a data structure like a BTreeMap. Sorting of strings for human consumption is significantly more complex (it will involve some type of unicode normalization, and will be locale-dependant).
I think that's slightly over-stating it. Say you are presenting a drop-down list, and the choices are sorted byte-wise. It's unlikely anyone will notice minor details in the sort order ( and in English, with typical capitalisation, it probably won't make any difference ). Most of the time I would say it's "good enough" for human consumption, at least for English.