use std::cmp::Ordering;
use std::ops::Mul;
pub(crate) fn vec_ord<Unit>(this: (Unit, Unit), other: (Unit, Unit)) -> Ordering
where
Unit: Ord + Copy + Mul<Output = Unit>,
{
let this_magnitude = this.0 * this.1;
let other_magnitude = other.0 * other.1;
match this_magnitude.cmp(&other_magnitude) {
Ordering::Equal => {
match (this.0.cmp(&other.0), this.1.cmp(&other.1)) {
(Ordering::Less | Ordering::Equal, Ordering::Less)
| (Ordering::Less, Ordering::Equal) => Ordering::Less,
(Ordering::Equal, Ordering::Equal) => Ordering::Equal,
(Ordering::Equal | Ordering::Greater, Ordering::Greater)
| (Ordering::Greater, Ordering::Equal) => Ordering::Greater,
(Ordering::Less, Ordering::Greater) => {
compare_smallest(this.1, this.0, other.1, other.0)
}
(Ordering::Greater, Ordering::Less) => {
compare_smallest(this.0, this.1, other.0, other.1)
}
}
}
other => other,
}
}
fn compare_smallest<Unit>(a1: Unit, a2: Unit, b1: Unit, b2: Unit) -> Ordering
where
Unit: Ord + Copy,
{
match b1.cmp(&a2) {
Ordering::Less => Ordering::Greater,
Ordering::Equal => {
if b2 < a1 {
Ordering::Greater
} else {
Ordering::Less
}
}
Ordering::Greater => Ordering::Less,
}
}