21个版本 (3个稳定版)
1.1.0 | 2023年4月19日 |
---|---|
1.0.1 | 2022年7月27日 |
0.11.0 | 2022年7月23日 |
#37 in 值格式化
10,074 每月下载量
在 14 个Crates中(10个直接) 使用
37KB
576 行
human-repr
生成字节、持续时间甚至吞吐量的美丽的人类可读表示!
简介
这个crate提供了一套完整的
- 计数功能,默认支持SI前缀:
k
、M
、G
、T
、P
、E
、Z
和Y
,包括可选的IEC前缀和“混合”前缀(见Rust特性)。 - 持续时间,支持SI前缀
ns
、µs
和ms
用于亚秒值,还包括一些自定义格式,如M:SS.s
(分钟:秒,保留1位小数)和H:MM:SS
(小时:分钟:秒)用于大于60秒的值。 - 吞吐量,支持SI接受的
/d
、/h
、/min
和/s
,当为每秒时,它甚至得到SI前缀,这是最快的。
此外,这个crate没有任何依赖项,经过良好的测试,并且非常快,生成表示的时间不到50ns!通过criterion基准测试验证。
它们与任何Rust原始数字以及Duration
一起工作!
// counts (bytes, bare, or any custom unit).
use human_repr::HumanCount;
assert_eq!("43.21GB", 43214321123_u64.human_count_bytes());
assert_eq!("74.9M", 74893200.human_count_bare());
assert_eq!("540.5kPackets", 540464_u32.human_count("Packets"));
assert_eq!("48.1°C", 48.132323432.human_count("°C"));
assert_eq!("123k🦀", 123e3.human_count("🦀"));
// durations with primitives.
use human_repr::HumanDuration;
assert_eq!("1.8ns", 0.0000000018.human_duration());
assert_eq!("15.6µs", 0.0000156.human_duration());
assert_eq!("10ms", 0.01.human_duration());
assert_eq!("3.44s", 3.435999.human_duration());
assert_eq!("19:20.4", 1160.36.human_duration());
assert_eq!("1:14:48", 4488u16.human_duration());
// durations with std's Duration.
use std::time::Duration;
assert_eq!("15.6µs", Duration::from_nanos(15_600).human_duration());
assert_eq!("10ms", Duration::from_secs_f64(0.01).human_duration());
assert_eq!("1:14:48", Duration::new(4488, 395_000_000).human_duration());
// throughputs (bytes, bare, or any custom unit).
use human_repr::HumanThroughput;
assert_eq!("1.2MB/s", 1248632.human_throughput_bytes());
assert_eq!("9/d", 0.000104166666667.human_throughput_bare());
assert_eq!("6.1tests/min", 0.101265.human_throughput("tests"));
assert_eq!("54°C/h", 0.015.human_throughput("°C"));
assert_eq!("123M⭐/s", 123e6.human_throughput("⭐"));
📌 1.1系列的新增功能
这个版本主要
- 包括一个用于
serde
的可选功能; - 使用
Cow
来代替泛型单位(可能更优化的二进制); - 将吞吐量中的分钟符号从
m
改为min
(这似乎是实际接受的SI符号)。
同时完善了所有细节。
1.0 系列新特性
此crate升级到1.0!🎉 达到这一步有很多改进...
从1.0版本开始,移除了 HumanRepr
特性。现在有单独的特性用于每个概念。
我意识到单独的特性更灵活,所以我只在实际需要的地方实现它们,同时可以独立地进行演变。
特性名称也变得更简单:HumanCount、HumanDuration和HumanThroughput。
0.11系列新特性
从版本0.11开始,为 &str
的 PartialEq
实现不会分配任何字符串!
我开发了一个特别有趣的 Write
实现,它将部分序列与 Display
实现将生成的内容进行比较!非常有意思
0.10系列新特性
从版本0.10开始,Debug
实现将显示原始值和最终表示!非常酷
# use human_repr::{HumanDuration, HumanThroughput};
assert_eq!("HumanDuration { val: 1.56e-5 } -> 15.6µs", format!("{:?}", 0.0000156.human_duration()));
assert_eq!(r#"HumanThroughput { val: 0.015, unit: "°C" } -> 54°C/h"#, format!("{:?}", 0.015.human_throughput("°C")));
0.4系列新特性
从版本0.4开始,生成输出时不再分配任何字符串!我返回了实现了 Display
的结构体,所以你可以打印它们而无需进行堆分配!如果你确实需要字符串,只需简单的 .to_string()
即可。
如何使用它
将此依赖项添加到你的Cargo.toml文件
human-repr = "1"
然后只需使用所需的特性!
use human_repr::{HumanCount, HumanDuration, HumanThroughput};
3000_u16.human_count("bytes");
(-5i8).human_count_bytes();
4244.32_f32.human_duration();
0.000000000004432_f64.human_duration();
# use std::time::Duration;
Duration::from_secs_f64(0.00432).human_duration();
8987_isize.human_throughput("transactions");
93321_usize.human_throughput_bytes();
它们适用于所有Rust原生数字类型:u8
、u16
、u32
、u64
、u128
、usize
、f32
、f64
、i8
、i16
、i32
、i64
、i128
、isize
,以及 Duration
类型。
请注意,
std
的Duration
提供了类似的Debug
实现功能,但它并不太 人性# use human_repr::HumanDuration; # use std::time::Duration; let default = format!("{:?}", Duration::new(0, 14184293)); assert_eq!("14.184293ms", default); // 😫👎 assert_eq!("14.2ms", Duration::new(0, 14184293).human_duration()); // 😃👍
当然,我还提供了它没有的分钟和小时视图...
# use human_repr::HumanDuration; # use std::time::Duration; let default = format!("{:?}", Duration::new(10000, 1)); assert_eq!("10000.000000001s", default); // 😫👎 assert_eq!("2:46:40", Duration::new(10000, 1).human_duration()); // 😃👍
某些方法提供的 unit
参数意味着你正在处理的实体,例如“字节”、“任务”、“它”、“°C”、“🍎”,等等。
字节(作为“B”)和裸单位有专门的方法供你方便使用。
Rust功能
根据SI标准,千字节中有1000字节。
还有一个标准称为 IEC,其中1 kibibyte
包含1024个字节,但这个标准仅适用于测量那些自然是以2为幂的量,例如内存条。在主要操作系统中的文件大小也正在改为使用1000的除数。
注意不要使用SI前缀来表示IEC量,这将是不正确的。
但我仍然支持它,如果你真的想的话 ;)
默认情况下,human-repr
使用SI前缀,1000
除数,并且在前缀/单位之间没有空格。
该库支持以下可选特性
space
=> 在值和前缀/单位之间包含空格:48 B
而不是48B
,15.6 µs
而不是15.6µs
,以及12.4 kB/s
而不是12.4kB/s
;iec
=> 使用IEC前缀而不是SI前缀:Ki
、Mi
、Gi
、Ti
、Pi
、Ei
、Zi
、Yi
(意味着1024
);1024
=> 使用1024
除数,无论iec
是否启用(即SI模式),小写k
转换为大写'K'
;serde
=> 启用序列化和反序列化支持。
人类持续时间魔咒
在设计人类持续时间行为时,我只使用了一个关键概念:清晰性。
3.44s
比比3.43584783784s
更有意义,而14.1µs
比比.0000141233333s
要好得多。
所以,我所做的就是:将值四舍五入到最多两位小数(较大值有更多小数位),并找到表示它们的最佳前缀,最小化输出值小于 1
。最佳前缀的搜索甚至考虑了应用四舍五入后的结果!
0.000999999
并不会变成999.9µs
(截断)或1000µs
(不良前缀),它将自动升级到下一个1ms
!
人类持续时间前缀无缝地从纳秒变化到小时!
- 小于60秒的值以
SS[.ss]前缀
的形式呈现,最多两位小数; - 从1分钟开始,它变为
M:SS[.s]
; - 从1小时开始,它变为
H:MM:SS
; - 将
.0
和.00
从输出中移除,而不是生成它们,这是在算法中直接处理的。
人类的吞吐量魔法
我使用类似的逻辑来计算人类的吞吐量。人类的大脑对“吞吐量”这个词是多么的难以理解!
如果处理 123
个项目花费了 1165263
秒,那么它的速度有多快?这并不明显...
即使我们将持续时间除以项目数量,帮助也不是很大:9473 秒/项目仍然看起来不太好。有多快?我们无法确定。
嗯,我们每单位时间完成了多少个项目?
哦,我们只需要取倒数,所以是 0.000105555569858 项目/秒,这就是答案! 😂
为了使其更有意义,我们需要将其乘以 3600(一小时中的秒数),以获得每小时 0.38,这要好得多,然后再乘以 24(一天中的小时数),最终得到每天 9.12!现在我们知道这个过程有多快了! \o/
正如你所见,对我们的大脑来说,估计这一点并不容易...
人类的吞吐量前缀无缝地从每秒转换为每天!
- 和持续时间魔法一样,
.0
和.00
也不会被高效生成; - 当处于最快的单位(每秒)时,它还会自动插入 SI 前缀,因此我们得到
2.4MB/s
或6.42Gitems/s
👍
人类计数魔法
这是其中最简单的一个,我只是不断地除以当前的除数(1000 或 1024),直到值小于那个值。完全没有使用对数或指数的奇怪业务。
四舍五入也得到了处理,因此没有截断或不良前缀,小数位数也随着前缀的增大而增加,而 .0
和 .00
也永远不会生成。
变更日志亮点
- 1.1.x 2023 年 4 月 19 日:为 serde 新增了可选功能,使用 Cow 而不是泛型为单位,将吞吐量中分钟的符号从
m
更改为min
,整体优化 - 1.0.x 2022 年 7 月 26 日:删除了
HumanRepr
trait,现在有针对每个概念的单独 trait:HumanCount
、HumanDuration
和HumanThroughput
- 0.11.x 2022 年 7 月 22 日:为
&str
新增了 PartialEq 实现,这甚至更快,并且不分配任何字符串 - 0.10.x 2022 年 7 月 17 日:添加了带有原始值和渲染值的 Debug 实现,添加了新的“裸单位”方法变体,从默认功能中删除
space
- 0.9.x 2022 年 6 月 22 日:不要在格式字符串中使用捕获的标识符,以支持更广泛的 Rust 版本,而不是仅支持 >= 1.58
- 0.8.x 2022 年 6 月 12 日:将
nospace
功能更改为space
,以避免负逻辑(现在是默认值,以保持行为) - 0.7.x 2022 年 6 月 4 日:通过新的 trait
HumanReprDuration
支持 std::time::Duration,在分钟表示中包含一个小数位 - 0.6.x 2022 年 6 月 4 日:使用新的
ops::Neg
实现,提高了对有符号数的支持 - 0.5.x 2022 年 6 月 3 日:添加了分钟表示 M:SS,介于秒和完整的 H:MM:SS 之间
- 0.4.x 2022年6月3日:通过Display引入新的渲染引擎,速度更快且不分配任何字符串
- 0.3.x 2022年6月1日:仅支持一组新的前缀,用于
1024
(不包含iec
) - 0.2.x 2022年6月1日:更灵活的API(
impl AsRef<str>
),大幅改进了文档 - 0.1.x 2022年6月1日:首次发布,包括readme、方法和模块文档,描述已实现的功能
许可证
本软件受MIT许可证的许可。完整的许可证文本请参阅顶级分发目录中的LICENSE文件。
维护开源项目很困难且耗时,我已经为此投入了大量的❤️和努力。
如果您欣赏我的工作,可以通过捐赠来支持我!谢谢 😊
依赖项
~170KB