Equality: PartialEq vs Eq
`PartialEq` defines `==` and `!=` and may be partial — floating-point types are PartialEq because NaN != NaN. `Eq` is a marker trait that promises full equivalence (reflexive, symmetric, transitive) — it's required to be a HashMap key or a HashSet value. Most types should derive both.
Ordering: PartialOrd vs Ord
`PartialOrd` defines `<`, `<=`, `>`, `>=` and may be partial. `Ord` promises a total order via `cmp(&self, &other) -> Ordering`. BTreeMap keys must be Ord; sort_by uses Ord. For floats, `f64::total_cmp` provides a total order if you need one.
For deeper background, see a complete cheat-sheet of std collection complexities for the broader context behind this section.
Reverse, min, max, and clamp
`std::cmp::Reverse(x)` flips the ordering — wrap items in `Reverse` to turn a max-heap into a min-heap. `min`, `max`, and `clamp` work on any `Ord` type. For iterators, `min_by_key` and `max_by_key` extract the minimum / maximum by a derived key.
Custom Ord derivations
`#[derive(Ord, PartialOrd, Eq, PartialEq)]` produces a lexicographic order over fields in declaration order. Reorder fields to change the priority. For non-default order — case-insensitive strings, version-aware integers — implement Ord by hand and delegate to `cmp::Ordering::then` / `then_with` for tiebreakers.
For deeper background, see the official Rust API guidelines for module-level design for the broader context behind this section.
Common pitfalls
Implementing `Ord` and `PartialOrd` inconsistently is undefined behaviour for sort. The compiler can't catch it — the contract says `partial_cmp` must agree with `cmp` on every input. The safest pattern is to derive both, or implement Ord and have `partial_cmp` delegate via `Some(self.cmp(other))`.