Rust时间解析库go-parse-duration的使用,支持Go风格的高精度持续时间字符串解析与转换
Rust时间解析库go-parse-duration的使用,支持Go风格的高精度持续时间字符串解析与转换
parse-duration-rs是Golang parse duration time.ParseDuration
的Rust实现版本。它可以解析短格式的持续时间字符串,如100ms
、1h45m
和3ns
,并返回纳秒级的持续时间。
安装
在Cargo.toml中添加以下依赖:
[dependencies]
go-parse-duration = "0.1"
示例
基本使用
use go_parse_duration::{parse_duration, Error};
fn parse() -> Result<i64, Error> {
let d = parse_duration("300us")?; // 解析300微秒
Ok(d)
}
与Chrono结合使用
可以轻松转换为Chrono的Duration类型:
use chrono::Duration;
use go_parse_duration::{parse_duration, Error};
fn parse() -> Result<Duration, Error> {
let d = parse_duration("1m")?; // 解析1分钟
Ok(Duration::nanoseconds(d))
}
完整示例代码
use go_parse_duration::{parse_duration, Error};
use chrono::Duration;
fn main() -> Result<(), Error> {
// 示例1:基本使用
let micros = parse_duration("300us")?;
println!("300微秒 = {}纳秒", micros);
// 示例2:复杂时间表达式
let complex = parse_duration("1h30m15s")?;
println!("1小时30分15秒 = {}纳秒", complex);
// 示例3:与Chrono结合
let chrono_duration = Duration::nanoseconds(parse_duration("45m")?);
println!("45分钟 = {:?}", chrono_duration);
Ok(())
}
完整功能演示
下面是一个更全面的示例,展示了go-parse-duration库的各种用法:
use go_parse_duration::{parse_duration, Error};
use chrono::Duration;
fn main() -> Result<(), Error> {
// 1. 解析各种时间单位
println!("1纳秒: {}", parse_duration("1ns")?);
println!("1微秒: {}", parse_duration("1us")?);
println!("1毫秒: {}", parse_duration("1ms")?);
println!("1秒: {}", parse_duration("1s")?);
println!("1分钟: {}", parse_duration("1m")?);
println!("1小时: {}", parse_duration("1h")?);
// 2. 组合时间单位
println!("1.5小时: {}", parse_duration("1h30m")?);
println!("2天3小时5分: {}", parse_duration("48h3h5m")?); // 注意:不支持"d"单位
// 3. 与Chrono配合使用
let duration = Duration::nanoseconds(parse_duration("2h30m")?);
println!("2小时30分钟 = {:?}", duration);
// 4. 错误处理示例
match parse_duration("invalid") {
Ok(val) => println!("解析结果: {}", val),
Err(e) => println!("解析错误: {}", e),
}
Ok(())
}
注意事项
- 该库目前不支持"天"(d)和"周"(w)等单位,需要转换为小时使用
- 时间字符串中不能包含空格
- 返回值为纳秒单位的i64整数
- 可以无缝与chrono库的Duration类型转换
作者
Armin Primadi (@ Sahamee)
1 回复
Rust时间解析库go-parse-duration使用指南
介绍
go-parse-duration
是一个Rust库,用于解析Go风格的高精度持续时间字符串并将其转换为标准的时间单位。这个库特别适合需要处理人类可读时间间隔字符串的场景,比如配置文件、命令行参数或API响应中的时间参数。
主要特性
- 支持Go语言风格的持续时间字符串格式
- 高精度解析(纳秒级)
- 简单易用的API
- 将字符串转换为标准时间单位(如秒、毫秒等)
安装
在Cargo.toml中添加依赖:
[dependencies]
go-parse-duration = "0.1"
使用方法
基本用法
use go_parse_duration::parse;
fn main() {
match parse("1h30m") {
Ok(duration) => {
println!("总秒数: {}", duration.as_secs());
println!("总毫秒数: {}", duration.as_millis());
}
Err(e) => println!("解析错误: {}", e),
}
}
支持的格式
库支持以下时间单位:
- 纳秒 “ns”
- 微秒 “us” (或 “µs”)
- 毫秒 “ms”
- 秒 “s”
- 分钟 “m”
- 小时 “h”
- 天 “d”
- 周 “w”
示例
use go_parse_duration::parse;
use std::time::Duration;
fn main() {
let cases = vec![
"300ms",
"2h45m",
"1.5h",
"2h30m10s500ms",
"1w2d",
"100ns",
];
for input in cases {
match parse(input) {
Ok(duration) => {
println!("'{}' => {:?}", input, duration);
}
Err(e) => println!("错误: {}", e),
}
}
}
转换为特定单位
use go_parse_duration::parse;
fn main() {
let duration = parse("1.5h").unwrap();
println!("小时: {}", duration.as_secs_f64() / 3600.0);
println!("分钟: {}", duration.as_secs_f64() / 60.0);
println!("秒: {}", duration.as_secs());
println!("毫秒: {}", duration.as_millis());
println!("微秒: {}", duration.as_micros());
println!("纳秒: {}", duration.as_nanos());
}
错误处理
use go_parse_duration::parse;
fn main() {
let result = parse("1hour30minutes");
match result {
Ok(duration) => println!("解析成功: {:?}", duration),
Err(e) => println!("解析失败: {}", e),
}
}
实际应用示例
配置文件中解析超时设置
use go_parse_duration::parse;
use std::time::Duration;
struct Config {
timeout: Duration,
}
impl Config {
fn new(timeout_str: &str) -> Result<Self, String> {
parse(timeout_str)
.map(|timeout| Config { timeout })
.map_err(|e| format!("无效的超时设置: {}", e))
}
}
fn main() {
let config = Config::new("30s").unwrap();
println!("超时设置为: {:?}", config.timeout);
}
CLI工具中的时间参数解析
use go_parse_duration::parse;
use clap::Parser;
#[derive(Parser)]
struct Cli {
#[clap(short, long, value_parser = parse_duration)]
interval: std::time::Duration,
}
fn parse_duration(s: &str) -> Result<std::time::Duration, String> {
parse(s).map_err(|e| e.to_string())
}
fn main() {
let args = Cli::parse();
println!("将每隔 {:?} 运行一次", args.interval);
}
注意事项
- 时间单位必须按照从大到小的顺序排列(例如"1h30m"正确,"30m1h"不正确)
- 支持小数(如"1.5h"表示1小时30分钟)
- 不支持负数时间间隔
- 空字符串会被解析为0持续时间
完整示例
以下是一个结合配置文件解析和CLI参数解析的完整示例:
use go_parse_duration::parse;
use std::time::Duration;
use clap::Parser;
use serde::Deserialize;
use std::fs;
// 配置文件结构体
#[derive(Debug, Deserialize)]
struct AppConfig {
default_timeout: String,
retry_interval: String,
}
// CLI参数结构体
#[derive(Parser, Debug)]
struct CliArgs {
#[clap(short, long, value_parser = parse_duration)]
custom_timeout: Option<Duration>,
#[clap(short, long)]
config_path: Option<String>,
}
// 解析持续时间字符串的辅助函数
fn parse_duration(s: &str) -> Result<Duration, String> {
parse(s).map_err(|e| e.to_string())
}
fn main() {
// 解析CLI参数
let args = CliArgs::parse();
// 加载配置文件
let config = match args.config_path {
Some(path) => {
let config_str = fs::read_to_string(&path)
.expect(&format!("无法读取配置文件: {}", path));
toml::from_str::<AppConfig>(&config_str)
.expect(&format!("无效的配置文件格式: {}", path))
}
None => {
println!("未指定配置文件,使用默认值");
AppConfig {
default_timeout: "30s".to_string(),
retry_interval: "5m".to_string(),
}
}
};
// 解析配置中的时间参数
let default_timeout = parse(&config.default_timeout)
.expect("无效的默认超时设置");
let retry_interval = parse(&config.retry_interval)
.expect("无效的重试间隔设置");
// 优先使用CLI参数中的设置
let timeout = args.custom_timeout.unwrap_or(default_timeout);
println!("当前配置:");
println!("超时时间: {:?}", timeout);
println!("重试间隔: {:?}", retry_interval);
// 模拟使用这些时间参数
println!("将使用 {} 秒超时和 {} 秒重试间隔",
timeout.as_secs(),
retry_interval.as_secs());
}
这个完整示例展示了如何:
- 从配置文件中解析持续时间字符串
- 从CLI参数中解析持续时间字符串
- 处理解析错误
- 在实际应用中使用解析得到的时间参数
要运行此示例,你需要在Cargo.toml中添加以下依赖:
[dependencies]
go-parse-duration = "0.1"
clap = { version = "4.0", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
toml = "0.7"