I'm writing code for a command line tool in Rust. I'm using Crate clap to get and parse command line arguments, I need to get three arguments: --date
, --time
and --timezone
.
For --date
and --time
I'm using types chrono::NaiveDate and chrono::NaiveTime respectively and it works fine.
src/main.rs
use clap::Parser;
use chrono::prelude::*;
// CLI struct
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)] // Read from `Cargo.toml`
pub struct Cli {
/// Select a date in format YYYY-MM-DD.
#[arg(short, long, value_name = "DATE")]
date: Option<NaiveDate>,
/// Clocking time in format HH:MM:SS
#[arg(short, long, value_name = "TIME")]
time: Option<NaiveTime>,
}
fn main() {
let _cli: Cli = Cli::parse();
println!("{:#?}", _cli);
}
Output
$ cargo run -- --date 2021-05-13 --time 08:34:23
Finished dev [unoptimized + debuginfo] target(s) in 2.28s
Running `target/debug/tool --date 2021-05-13 --time '08:34:23'`
Cli {
date: Some(
2021-05-13,
),
time: Some(
08:34:23,
),
}
but when I want add --timezone
argument and use it as type chrono::FixedOffset, like this:
[...]
pub struct Cli {
/// Select a date in format YYYY-MM-DD.
#[arg(short, long, value_name = "DATE")]
date: Option<NaiveDate>,
/// Clocking time in format HH:MM:SS
#[arg(short, long, value_name = "TIME")]
time: Option<NaiveTime>,
/// Define local TimeZone
#[arg(long, value_name = "TIMEZONE")]
timezone: Option<FixedOffset>,
}
[...]
Rust compiler shows this error:
$ cargo run -- --date 2021-05-13 --time 08:34:23
Compiling tool v0.1.0 (~/rust/tool)
error[E0599]: the method `value_parser` exists for reference `&&&&&&_AutoValueParser<chrono::FixedOffset>`, but its trait bounds were not satisfied
--> src/main.rs:19:5
|
19 | /// Define local TimeZone
| ^^^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `&&&&&&_AutoValueParser<chrono::FixedOffset>` due to unsatisfied trait bounds
|
::: ~/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-4.0.18/src/builder/value_parser.rs:2171:1
|
2171 | pub struct _AutoValueParser<T>(std::marker::PhantomData<T>);
| ------------------------------ doesn't satisfy `_: clap::builder::via_prelude::_ValueParserViaParse`
|
::: ~/.cargo/registry/src/github.com-1ecc6299db9ec823/chrono-0.4.22/src/offset/fixed.rs:27:1
|
27 | pub struct FixedOffset {
| ----------------------
| |
| doesn't satisfy `chrono::FixedOffset: From<&'s std::ffi::OsStr>`
| doesn't satisfy `chrono::FixedOffset: From<&'s str>`
| doesn't satisfy `chrono::FixedOffset: From<OsString>`
| doesn't satisfy `chrono::FixedOffset: From<std::string::String>`
| doesn't satisfy `chrono::FixedOffset: FromStr`
| doesn't satisfy `chrono::FixedOffset: ValueEnum`
| doesn't satisfy `chrono::FixedOffset: ValueParserFactory`
|
= note: the following trait bounds were not satisfied:
`chrono::FixedOffset: ValueEnum`
which is required by `&&&&&_AutoValueParser<chrono::FixedOffset>: clap::builder::via_prelude::_ValueParserViaValueEnum`
`chrono::FixedOffset: ValueParserFactory`
which is required by `&&&&&&_AutoValueParser<chrono::FixedOffset>: clap::builder::via_prelude::_ValueParserViaFactory`
`chrono::FixedOffset: From<OsString>`
which is required by `&&&&_AutoValueParser<chrono::FixedOffset>: clap::builder::via_prelude::_ValueParserViaFromOsString`
`chrono::FixedOffset: From<&'s std::ffi::OsStr>`
which is required by `&&&_AutoValueParser<chrono::FixedOffset>: clap::builder::via_prelude::_ValueParserViaFromOsStr`
`chrono::FixedOffset: From<std::string::String>`
which is required by `&&_AutoValueParser<chrono::FixedOffset>: clap::builder::via_prelude::_ValueParserViaFromString`
`chrono::FixedOffset: From<&'s str>`
which is required by `&_AutoValueParser<chrono::FixedOffset>: clap::builder::via_prelude::_ValueParserViaFromStr`
`chrono::FixedOffset: FromStr`
which is required by `_AutoValueParser<chrono::FixedOffset>: clap::builder::via_prelude::_ValueParserViaParse`
= note: this error originates in the macro `clap::value_parser` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0599`.
error: could not compile `tool` due to 2 previous errors
Should I use another type for timezone
variable?
Should I implement FromStr trait to FixedOffset struct?
I could use timezone
variable as Type String, and it works, but I want to use a specific type for TimeZone or Offset, for instance, to save +01:00
value. I will have to manage this param isolated.
I don't want to use chrono::DateTime struct because I will use default values for these arguments, usually, the user only will define --time
parameter and I won't force him to write all DateTime.
Thank you
You can't implement
FromStr
forFixedOffset
because you wrote neither theFromStr
trait nor theFixedOffset
struct and because of the orphan rule. However you will indeed need to write a function that converts a string into aFixedOffset
and pass it to clap using thevalue_parser
attribute:Playground