use core::cmp::Ordering;
use core::fmt;
use Comparator;
#[derive(Copy, Clone, Debug)]
pub struct Reversed<T>(pub(crate) T);
impl<T, U> Comparator<U> for Reversed<T>
where
T: Comparator<U>,
U: ?Sized,
{
fn compare(&self, a: &U, b: &U) -> Ordering {
self.0.compare(a, b).reverse()
}
}
#[derive(Copy, Clone, Debug)]
pub struct ThenComparing<T, U>(pub(crate) T, pub(crate) U);
impl<T, U, W> Comparator<W> for ThenComparing<T, U>
where
T: Comparator<W>,
U: Comparator<W>,
W: ?Sized,
{
fn compare(&self, a: &W, b: &W) -> Ordering {
self.0.compare(a, b).then_with(|| self.1.compare(a, b))
}
}
#[derive(Copy, Clone)]
pub struct ThenComparingByKey<T, F> {
pub(crate) comparator: T,
pub(crate) f: F,
}
impl<T, F> fmt::Debug for ThenComparingByKey<T, F>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ThenComparingByKey")
.field("comparator", &self.comparator)
.finish()
}
}
impl<T, F, U, W> Comparator<U> for ThenComparingByKey<T, F>
where
T: Comparator<U>,
F: Fn(&U) -> W,
U: ?Sized,
W: Ord,
{
fn compare(&self, a: &U, b: &U) -> Ordering {
self.comparator
.compare(a, b)
.then_with(|| (self.f)(&a).cmp(&(self.f)(&b)))
}
}
pub fn comparing<F, T, U>(f: F) -> Comparing<F>
where
F: Fn(&T) -> U,
T: ?Sized,
U: Ord,
{
Comparing { f }
}
#[derive(Clone, Copy)]
pub struct Comparing<F> {
f: F,
}
impl<F> fmt::Debug for Comparing<F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Comparing").finish()
}
}
impl<F, T, U> Comparator<T> for Comparing<F>
where
F: Fn(&T) -> U,
T: ?Sized,
U: Ord,
{
fn compare(&self, a: &T, b: &T) -> Ordering {
(self.f)(a).cmp(&(self.f)(b))
}
}
pub fn natural_order() -> NaturalOrder {
NaturalOrder { _priv: () }
}
#[derive(Copy, Clone, Default)]
pub struct NaturalOrder {
_priv: (),
}
impl fmt::Debug for NaturalOrder {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("NaturalOrder").finish()
}
}
impl<T> Comparator<T> for NaturalOrder
where
T: ?Sized + Ord,
{
fn compare(&self, a: &T, b: &T) -> Ordering {
a.cmp(b)
}
}
pub fn reverse_order() -> ReverseOrder {
ReverseOrder { _priv: () }
}
#[derive(Copy, Clone, Default)]
pub struct ReverseOrder {
_priv: (),
}
impl fmt::Debug for ReverseOrder {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ReverseOrder").finish()
}
}
impl<T> Comparator<T> for ReverseOrder
where
T: ?Sized + Ord,
{
fn compare(&self, a: &T, b: &T) -> Ordering {
b.cmp(a)
}
}