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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
extern crate num_integer;
use std::fmt::{self, Display};
use num_integer::Integer;
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Ordinal<T>(pub T);
impl<T> Display for Ordinal<T>
where
T: Integer + Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = self.0.to_string();
let suffix = if s.ends_with("1") && !s.ends_with("11") {
"st"
} else if s.ends_with("2") && !s.ends_with("12") {
"nd"
} else if s.ends_with("3") && !s.ends_with("13") {
"rd"
} else {
"th"
};
write!(f, "{}{}", s, suffix)
}
}
#[cfg(test)]
mod tests {
extern crate num_bigint;
extern crate num_traits;
use self::num_bigint::{BigInt, BigUint};
use self::num_traits::One;
use super::*;
#[test]
fn test_display() {
for case in vec![
(-4, "-4th"),
(-3, "-3rd"),
(-2, "-2nd"),
(-1, "-1st"),
(0, "0th"),
(1, "1st"),
(2, "2nd"),
(3, "3rd"),
(4, "4th"),
(10, "10th"),
(11, "11th"),
(12, "12th"),
(13, "13th"),
(14, "14th"),
(20, "20th"),
(21, "21st"),
(22, "22nd"),
(23, "23rd"),
(24, "24th"),
(100, "100th"),
(101, "101st"),
(102, "102nd"),
(103, "103rd"),
(104, "104th"),
(110, "110th"),
(111, "111th"),
(112, "112th"),
(113, "113th"),
(114, "114th"),
(120, "120th"),
(121, "121st"),
(122, "122nd"),
(123, "123rd"),
(124, "124th"),
] {
assert_eq!(case.1, Ordinal(case.0).to_string());
}
}
#[test]
fn test_types() {
assert_eq!("1st", Ordinal(1i8).to_string());
assert_eq!("1st", Ordinal(1i16).to_string());
assert_eq!("1st", Ordinal(1i32).to_string());
assert_eq!("1st", Ordinal(1i64).to_string());
assert_eq!("1st", Ordinal(1isize).to_string());
assert_eq!("1st", Ordinal(1u8).to_string());
assert_eq!("1st", Ordinal(1u16).to_string());
assert_eq!("1st", Ordinal(1u32).to_string());
assert_eq!("1st", Ordinal(1u64).to_string());
assert_eq!("1st", Ordinal(1usize).to_string());
assert_eq!("1st", Ordinal(BigInt::one()).to_string());
assert_eq!("1st", Ordinal(BigUint::one()).to_string());
}
}