Rust时间解析库go-parse-duration的使用,支持Go风格的高精度持续时间字符串解析与转换

Rust时间解析库go-parse-duration的使用,支持Go风格的高精度持续时间字符串解析与转换

parse-duration-rs是Golang parse duration time.ParseDuration的Rust实现版本。它可以解析短格式的持续时间字符串,如100ms1h45m3ns,并返回纳秒级的持续时间。

安装

在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(())
}

注意事项

  1. 该库目前不支持"天"(d)和"周"(w)等单位,需要转换为小时使用
  2. 时间字符串中不能包含空格
  3. 返回值为纳秒单位的i64整数
  4. 可以无缝与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);
}

注意事项

  1. 时间单位必须按照从大到小的顺序排列(例如"1h30m"正确,"30m1h"不正确)
  2. 支持小数(如"1.5h"表示1小时30分钟)
  3. 不支持负数时间间隔
  4. 空字符串会被解析为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());
}

这个完整示例展示了如何:

  1. 从配置文件中解析持续时间字符串
  2. 从CLI参数中解析持续时间字符串
  3. 处理解析错误
  4. 在实际应用中使用解析得到的时间参数

要运行此示例,你需要在Cargo.toml中添加以下依赖:

[dependencies]
go-parse-duration = "0.1"
clap = { version = "4.0", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
toml = "0.7"
回到顶部