使用拍手的#[derive(parser)],我如何接受std :: time ::持续时间?

发布于 2025-01-30 12:36:33 字数 284 浏览 3 评论 0 原文

我想在命令行上接受 std :: Time ::持续时间。我正在使用 clap ##[derive(parser)] 生成参数解析器。有什么办法可以直接接受输入,而不是接受数字并在以后进行转换?

这样的事情:

#[derive(Debug, Parser)]
pub struct Config {
    #[clap( ??? )]
    interval: std::time::Duration,
}

I want to accept a std::time::Duration on a command line. I'm using clap with #[derive(Parser)] to generate the parameter parser. Is there any way I can directly accept an input, rather than accepting a number and doing the conversion later?

Something like this:

#[derive(Debug, Parser)]
pub struct Config {
    #[clap( ??? )]
    interval: std::time::Duration,
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

三生池水覆流年 2025-02-06 12:36:34

clap 4

use clap::Parser;
use std::time::Duration;
use std::num::ParseIntError;

#[derive(Debug, Parser)]
pub struct Config {
    #[arg(value_parser = |arg: &str| -> Result<Duration, ParseIntError> {Ok(Duration::from_secs(arg.parse()?))})]
    interval_secs: Duration,
}

文档的紧凑型版本:

https://docs.rs/clap/latest/clap/macro.value_parser.html

Compact version for Clap 4

use clap::Parser;
use std::time::Duration;
use std::num::ParseIntError;

#[derive(Debug, Parser)]
pub struct Config {
    #[arg(value_parser = |arg: &str| -> Result<Duration, ParseIntError> {Ok(Duration::from_secs(arg.parse()?))})]
    interval_secs: Duration,
}

Docs for value_parser:

https://docs.rs/clap/latest/clap/builder/struct.ValueParser.html#method.new

https://docs.rs/clap/latest/clap/macro.value_parser.html

风苍溪 2025-02-06 12:36:34

我认为没有一种方法可以区分 u8 或与 std :: Time ::持续时间在命令行本身上的其他方法。 那么您应该能够执行此类操作。

struct Config {
    #[structopt(short = "i", long = "interval")]
    interval: std::time::Duration,
}

也就是说,如果您实现 for distation :但是,您绝对更容易采用 u8 , >并在 main()或类似过程中进行转换。

I don't think there's a way to differentiate a u8 or whatever from a std::time::Duration on the command line itself. That said, you should be able to do something like this if you implement FromStr for Duration:

struct Config {
    #[structopt(short = "i", long = "interval")]
    interval: std::time::Duration,
}

But it definitely seems easier to take something like a u8 and do a conversion in main() or similar.

伴我心暖 2025-02-06 12:36:33

拍手3.0:

要进行自定义解析,您应该使用#[clap(parse(try_from_str = ...))] 并定义一个自定义函数以解析参数。这是一个例子:

use clap::Parser;

#[derive(Debug, Parser)]
pub struct Config {
    #[clap(parse(try_from_str = parse_duration))]
    interval: std::time::Duration,
}

fn parse_duration(arg: &str) -> Result<std::time::Duration, std::num::ParseIntError> {
    let seconds = arg.parse()?;
    Ok(std::time::Duration::from_secs(seconds))
}

拍手4.0:

几乎与上面相同;辅助功能可以保持不变,但是属性语法已经改变:

use clap::Parser;

#[derive(Debug, Parser)]
pub struct Config {
    #[arg(value_parser = parse_duration)]
    interval: std::time::Duration,
}

fn parse_duration(arg: &str) -> Result<std::time::Duration, std::num::ParseIntError> {
    let seconds = arg.parse()?;
    Ok(std::time::Duration::from_secs(seconds))
}

通过humanantime进行解析,

解析非常有限(我不知道您期望持续时间是什么格式),但它显示了您如何做的它。

如果您想在持续时间的争论中灵活地提高论点,请考虑使用“ 5S” 或“ 3小时” 之类的单元标签。您可以使用其辅助功能将其解析为 std :: Time ::持续时间(使用CLAP 4语法):

use clap::Parser;

#[derive(Debug, Parser)]
pub struct Config {
    #[clap(value_parser = humantime::parse_duration, default_value = "500ms")]
    interval: std::time::Duration,
}

或者您可以使用 humantime ::持续时间 没有特殊属性,因为它在str 上实现了

use clap::Parser;

#[derive(Debug, Parser)]
pub struct Config {
    #[clap(default_value = "500ms")]
    interval: humantime::Duration,
}

Clap 3.0:

To do custom parsing, you should use #[clap(parse(try_from_str = ...))] and define a custom function to parsing the argument. Here's an example:

use clap::Parser;

#[derive(Debug, Parser)]
pub struct Config {
    #[clap(parse(try_from_str = parse_duration))]
    interval: std::time::Duration,
}

fn parse_duration(arg: &str) -> Result<std::time::Duration, std::num::ParseIntError> {
    let seconds = arg.parse()?;
    Ok(std::time::Duration::from_secs(seconds))
}

Clap 4.0:

Almost same as above; the helper function can stay the same, but the attribute syntax has changed:

use clap::Parser;

#[derive(Debug, Parser)]
pub struct Config {
    #[arg(value_parser = parse_duration)]
    interval: std::time::Duration,
}

fn parse_duration(arg: &str) -> Result<std::time::Duration, std::num::ParseIntError> {
    let seconds = arg.parse()?;
    Ok(std::time::Duration::from_secs(seconds))
}

Parsing with humantime

This parsing is pretty limited (I don't know what format you'd expect the duration to be in), but it shows how you'd do it.

If you want to be flexible with your duration arguments, consider using a crate like humantime, which lets you provide durations with unit labels like "5s" or "3 hours". You can either use their helper function to parse into a std::time::Duration (using clap 4 syntax):

use clap::Parser;

#[derive(Debug, Parser)]
pub struct Config {
    #[clap(value_parser = humantime::parse_duration, default_value = "500ms")]
    interval: std::time::Duration,
}

Or you can use humantime::Duration without special attributes since it implements FromStr.

use clap::Parser;

#[derive(Debug, Parser)]
pub struct Config {
    #[clap(default_value = "500ms")]
    interval: humantime::Duration,
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文