1use chrono::prelude::*;
2use jam_types::{Slot, JAM_COMMON_ERA};
3
4pub fn slot_time(slot: Slot) -> String {
5 chrono::Local
6 .timestamp_opt(JAM_COMMON_ERA as i64 + slot as i64 * 6, 0)
7 .unwrap()
8 .format("%H:%M:%S")
9 .to_string()
10}
11
12pub fn slot(slot: Slot) -> String {
13 slot.to_string()
14 .as_bytes()
15 .rchunks(3)
16 .rev()
17 .map(std::str::from_utf8)
18 .collect::<Result<Vec<&str>, _>>()
19 .expect("converted from number; qed")
20 .join(",")
21}
22
23pub fn percent<T: Into<u128>>(n: T, d: T) -> String {
24 let ppm = (n.into() as f64 / d.into() as f64 * 100_000f64).ceil() / 1_000f64;
25 if ppm >= 1000.0 {
26 ppm.round()
27 } else if ppm >= 100.0 {
28 (ppm * 10f64).round() / 10f64
29 } else if ppm >= 10.0 {
30 (ppm * 100f64).round() / 100f64
31 } else {
32 ppm
33 }
34 .to_string()
35}
36
37pub fn bytes<T: Into<u128>>(n: T) -> String {
38 units(n, "B", 1024.0)
39}
40
41pub fn amount<T: Into<u128>>(n: T) -> String {
42 units(n, "", 1000.0)
43}
44
45pub fn gas<T: Into<u128>>(n: T) -> String {
46 units(n, "", 1000.0)
47}
48
49pub fn units<T: Into<u128>>(n: T, ones: &str, divisor: f64) -> String {
50 const UNITS: [&str; 7] = ["", "K", "M", "G", "T", "P", "E"];
51 let mut i = 0;
52 let mut n = n.into() as f64;
53 while n >= 999.5 && i > 0 || n >= 9999.5 {
54 n /= divisor;
55 i += 1;
56 }
57 let q = if n >= 100.0 {
58 1.0
59 } else if n >= 10.0 {
60 10.0
61 } else {
62 100.0
63 };
64 format!("{}{}", (n * q + 1.0e-14).round() / q, if i == 0 { ones } else { UNITS[i] })
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn amount_works() {
73 assert_eq!(amount(0u32), "0");
74 assert_eq!(amount(999u32), "999");
75 assert_eq!(amount(9_999u32), "9999");
76 assert_eq!(amount(10_000u32), "10K");
77 assert_eq!(amount(10_049u32), "10K");
78 assert_eq!(amount(10_050u32), "10.1K");
79 assert_eq!(amount(100_499u32), "100K");
80 assert_eq!(amount(100_500u32), "101K");
81 assert_eq!(amount(1_004_999u32), "1M");
82 assert_eq!(amount(1_005_000u32), "1.01M");
83 assert_eq!(amount(10_049_999u32), "10M");
84 assert_eq!(amount(10_050_000u32), "10.1M");
85 }
86}