unc_token/trait_impls/
display.rs

1use crate::{UncToken, ONE_MILLIUNC};
2
3/// UncToken Display implementation rounds up the token amount to the relevant precision point.
4/// There are 4 breakpoints:
5/// 1. exactly 0 UNC
6/// 2. <0.001 UNC
7/// 3. 0.001 - 0.999 UNC (uses 3 digits after the floating point)
8/// 4. >1 UNC (uses 2 digits after the floating point)
9impl std::fmt::Display for UncToken {
10    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11        if *self == UncToken::from_attounc(0) {
12            write!(f, "0 UNC")
13        } else if *self < UncToken::from_milliunc(1) {
14            write!(f, "<0.001 UNC")
15        } else if *self <= UncToken::from_milliunc(999) {
16            let milliunc_rounded_up =
17                self.as_attounc().saturating_add(ONE_MILLIUNC - 1) / ONE_MILLIUNC;
18            write!(f, "0.{:03} UNC", milliunc_rounded_up)
19        } else {
20            let unc_rounded_up =
21                self.as_attounc().saturating_add(10 * ONE_MILLIUNC - 1) / ONE_MILLIUNC / 10;
22            write!(
23                f,
24                "{}.{:02} UNC",
25                unc_rounded_up / 100,
26                unc_rounded_up % 100
27            )
28        }
29    }
30}
31
32#[cfg(test)]
33mod test {
34    use crate::UncToken;
35
36    #[test]
37    fn test_display() {
38        for (unc_tokens, expected_display) in [
39            (UncToken::from_attounc(0), "0 UNC"),
40            (UncToken::from_attounc(1), "<0.001 UNC"),
41            (UncToken::from_attounc(10u128.pow(21) - 1), "<0.001 UNC"),
42            (UncToken::from_attounc(10u128.pow(21)), "0.001 UNC"),
43            (UncToken::from_attounc(10u128.pow(21) + 1), "0.002 UNC"),
44            (UncToken::from_attounc(10u128.pow(21) * 2), "0.002 UNC"),
45            (
46                UncToken::from_attounc(10u128.pow(21) * 200),
47                "0.200 UNC",
48            ),
49            (
50                UncToken::from_attounc(10u128.pow(21) * 999),
51                "0.999 UNC",
52            ),
53            (
54                UncToken::from_attounc(10u128.pow(21) * 999 + 1),
55                "1.00 UNC",
56            ),
57            (UncToken::from_attounc(10u128.pow(24) - 1), "1.00 UNC"),
58            (UncToken::from_attounc(10u128.pow(24)), "1.00 UNC"),
59            (UncToken::from_attounc(10u128.pow(24) + 1), "1.01 UNC"),
60            (
61                UncToken::from_attounc(10u128.pow(21) * 1234),
62                "1.24 UNC",
63            ),
64            (
65                UncToken::from_attounc(10u128.pow(21) * 1500),
66                "1.50 UNC",
67            ),
68            (
69                UncToken::from_attounc(10u128.pow(21) * 10000),
70                "10.00 UNC",
71            ),
72            (
73                UncToken::from_attounc(10u128.pow(21) * 10500),
74                "10.50 UNC",
75            ),
76            (
77                UncToken::from_attounc(10u128.pow(21) * 100000 - 1),
78                "100.00 UNC",
79            ),
80            (
81                UncToken::from_attounc(10u128.pow(21) * 100000),
82                "100.00 UNC",
83            ),
84            (
85                UncToken::from_attounc(10u128.pow(21) * 100500),
86                "100.50 UNC",
87            ),
88            (
89                UncToken::from_attounc(10u128.pow(21) * 100000000),
90                "100000.00 UNC",
91            ),
92            (
93                UncToken::from_attounc(10u128.pow(21) * 100000500),
94                "100000.50 UNC",
95            ),
96        ] {
97            assert_eq!(
98                unc_tokens.to_string(),
99                expected_display,
100                "tokens: {}",
101                unc_tokens.as_attounc()
102            );
103        }
104    }
105}