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 日:删除了
HumanReprtrait,现在有针对每个概念的单独 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
