#duration-parser #duration #systemd #parse-duration #duration-string #format-duration #parser

fundu-systemd

快速且精确的 systemd 时间跨度解析器,将 rust 字符串解析为 Duration

3 个版本 (破坏性更新)

0.3.0 2023年8月7日
0.2.0 2023年7月9日
0.1.0 2023年6月26日

#1546 in 解析器实现

MIT 协议

250KB
2.5K SLoC

快速且精确的 systemd 时间跨度解析器,将 rust 字符串解析为 Duration


目录

概述

此 crate 提供了一个简单易用且快速的解析器,基于 fundu,旨在完全兼容 systemd 文档中指定的 systemd 时间跨度格式。

fundu-systemd 可以解析类似以下 rust 字符串

&str Duration
"2 h" Duration::positive(2 * 60 * 60, 0)
"2hours" Duration::positive(2 * 60 * 60, 0)
"second" Duration::positive(1, 0)
"48hr" Duration::positive(48 * 60 * 60, 0)
"12.3 seconds" Duration::positive(12, 300_000_000)
"1y 12month" Duration::positive(63_115_200, 0)
"999us +1d" Duration::positive(86_400, 999_000)
"55s500ms" Duration::positive(55, 500_000_000)
"300ms20s 5day" Duration::positive(20 + 5 * 60 * 60 * 24, 300_000_000)
"123456789" Duration::positive(123_456_789, 0) (默认:秒)
"100" Duration::positive(0, 100_000) (当默认设置为微秒时)
"infinity" 变量:当前正在使用的最大持续时间(见下文)

请注意,fundu 会解析成它自己的 Duration,它是其他 Durations(如 std::time::Durationchrono::Durationtime::Duration)的超集。有关如何轻松处理这些持续时间之间的转换的文档,请参阅 文档

目标受众

如果您

  • 需要快速可靠的 systemd 兼容的持续时间解析器
  • 希望它简单易用,无需进行大量自定义
  • 就像 systemd 格式一样
  • ...

如果您想自定义解析器以适应与 systemd 不兼容的格式,那么这个包可能不适合您。如果您想使用针对您需求定制的解析器,请参阅主 fundu 项目。

安装

将以下内容添加到 Cargo.toml

[dependencies]
fundu-systemd = "0.3.0"

或者使用 cargo add fundu-systemd 安装。

激活 chronotime 功能为 chrono::Durationtime::Duration 提供了 TryFrom 实现。从/to std::time::Duration 的转换不需要额外的功能。激活 serde 功能允许某些结构和枚举使用 serde 进行序列化或反序列化。

格式说明

支持的时间单位

  • nsecns(可以启用,默认情况下不包括这些)
  • usecusµs
  • msecms
  • secondssecondsecs
  • minutesminuteminm
  • hourshourhrh
  • daysdayd
  • weeksweekw
  • monthsmonthM(定义为 30.44 天或 1/12 年)
  • yearsyeary(定义为 365.25 天)

其他格式摘要

  • 仅允许像"123天"或带有分数"1.2天"的数字,但不允许有指数(如"3e9天"
  • 对于没有时间单位的数字(如"1234"),默认时间单位通常是second,但可以更改,因为在某些情况下systemd使用不同的粒度。
  • 允许没有数字的时间单位(如"second"),默认值为1
  • 解析的持续时间代表源字符串中指定的值(精确值,没有四舍五入错误,如浮点计算中可能发生的错误),就像systemd一样。
  • 支持的最大持续时间(Duration::MAX)为u64::MAX秒(18_446_744_073_709_551_615)和999_999_999纳秒。然而,systemd在没有纳秒的情况下解析时使用u64::MAX微秒作为最大持续时间,在有纳秒的情况下解析时使用u64::MAX纳秒。fundu-systemd提供了parseparse_nanos函数来反映这一点。如果您不喜欢systemd的最大持续时间,仍然可以通过parse_with_maxparse_nanos_with_max将此限制调整为从Duration::ZERODuration::MAX的持续时间。
  • 特殊值"infinity"评估为最大持续时间。注意,最大持续时间取决于是否解析时包含纳秒。如果将最大持续时间手动设置为不同的值,则评估为该最大持续时间。
  • 大于最大持续时间的解析持续时间(如"100000000000000years")饱和在最大持续时间。
  • 不允许负持续时间,也不允许中间有负持续时间,如"5day -1ms",尽管最终持续时间可能不是负数。
  • 任何前导空格、尾随空格或数字和时间单位之间的空格(如"1 \n sec")以及多个持续时间(如"1week \n 2minutes")都将被忽略,并遵循POSIX对空格的定义,即
    • 空格(' '
    • 水平制表符('\x09'
    • 换行符('\x0A'
    • 垂直制表符('\x0B'
    • 进纸符('\x0C'
    • 回车符('\x0D'

请参阅systemd的文档了解它们的格式。

基准测试

要在您的机器上运行基准测试,请克隆仓库

git clone https://github.com/fundu-rs/fundu.git
cd fundu

然后使用以下命令运行fundu-systemd基准测试

cargo bench --package fundu-systemd

上面的命令不会运行flamegraphiai-callgrind基准测试。

iai-callgrind(功能=with-iai)和flamegraph(功能=with-flamegraph)基准测试只能在Unix系统上运行。使用cargo的--features选项运行具有这些功能的基准测试。

为了大致了解解析时间,以下是某些输入的平均解析速度(四核3000MHz,8GB DDR3,Linux)

输入 平均解析时间
1 55.572纳秒(ns)
123456789.123456789 88.750纳秒(ns)
格式!("{}.{}", "1".重复(1022), "1".重复(1022)) 475.07纳秒(ns)
秒(s) 83.724纳秒(ns)
分钟(min) 133.26纳秒(ns)
1ns 1微秒(us) 200.59纳秒(ns)
1ns 1us 1毫秒(ms) 1秒(s) 379.75纳秒(ns)
1ns 1us 1ns 1us 391.54纳秒(ns)
"1ns 1微秒(us)".重复(100) 18.644微秒(µs)

许可协议

MIT许可(LICENSEhttp://opensource.org/licenses/MIT

依赖项

~205–630KB
~12K SLoC