1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use std::borrow::Borrow;
use std::convert::Infallible;
use std::fmt::Display;
use std::ops::Deref;
use std::pin::Pin;

use super::FmtEq;

/// A marker trait for types whose ordering is the same as ordering between its `Display`
/// representation.
///
/// When `T` implements `FmtOrd`, the following property must be upheld for all `a: T` and `b: T`:
///
/// ```
/// # let (a, b) = ("", "");
/// assert_eq!(a.cmp(&b), (*format!("{}", a)).cmp(&format!("{}", b)));
/// ```
///
/// In other words (assuming that no ill-defined specialization is involved):
///
/// ```text
/// a ⋛ b <-> a.to_string() ⋛ b.to_string()
/// ```
///
/// ## Colloraries
///
/// From `str: Ord` and the above property, it follows that `T` satisfies [`Ord`](std::cmp::Ord)
/// trait's contract.
///
/// ## Examples
///
/// Integer primitives do not satisfy the property.
///
/// ```
/// assert!(42 < 240);
/// // but...
/// assert!(42.to_string() > 240.to_string());
/// ```
///
/// Wrapping any `Display` type with [`fmt_cmp::Cmp`](crate::Cmp) makes it `FmtOrd`:
///
/// ```
/// assert!(fmt_cmp::Cmp(42) > fmt_cmp::Cmp(240));
/// ```
pub trait FmtOrd: Display + Ord + FmtEq {}

// Blanket impls for `#[fundamental]` pointer types.
impl<T: FmtOrd + ?Sized> FmtOrd for &T {}
impl<T: FmtOrd + ?Sized> FmtOrd for &mut T {}
impl<P: Borrow<<P as Deref>::Target> + Deref + Display> FmtOrd for Pin<P> where P::Target: FmtOrd {}

impl FmtOrd for str {}
// Both `false < true` and `"false" < "true"` hold coincidentally.
impl FmtOrd for bool {}

impl FmtOrd for Infallible {}

// `alloc` types.
#[cfg(feature = "alloc")]
impl<T: FmtOrd + ?Sized> FmtOrd for alloc::boxed::Box<T> {}
#[cfg(feature = "alloc")]
impl<T: FmtOrd + ?Sized> FmtOrd for alloc::rc::Rc<T> {}
#[cfg(feature = "alloc")]
impl<T: FmtOrd + ?Sized> FmtOrd for alloc::sync::Arc<T> {}
#[cfg(feature = "alloc")]
impl<T: FmtOrd + alloc::borrow::ToOwned + ?Sized> FmtOrd for alloc::borrow::Cow<'_, T> where
    T::Owned: Display
{
}
#[cfg(feature = "alloc")]
impl FmtOrd for alloc::string::String {}