我想使StructOpt
与枚举一起使用,以便每当用户通过-d sunday
时,它将被解析为Day::Sunday
:
#[macro_use]
extern crate structopt;
use std::path::PathBuf;
use structopt::StructOpt;
// My enum
enum Day {
Sunday, Monday
}
#[derive(Debug, StructOpt)]
#[structopt(name = "example", about = "An example of StructOpt usage.")]
struct Opt {
/// Set speed
#[structopt(short = "s", long = "speed", default_value = "42")]
speed: f64,
/// Input file
#[structopt(parse(from_os_str))]
input: PathBuf,
/// Day of the week
#[structopt(short = "d", long = "day", default_value = Day::Monday)]
day: Day,
}
fn main() {
let opt = Opt::from_args();
println!("{:?}", opt);
}
我当前的[[best解决方案是使用Option<String>
作为类型并传递自定义parse_day()
:
fn parse_day(day: &str) -> Result<Day, ParseError> {
match day {
"sunday" => Ok(Day::Sunday),
_ => Ok(Day::Monday)
}
Err("Could not parse a day")
}
FromStr
的任何类型,与FromStr
函数相距不远:parse_day
此外,use std::str::FromStr; impl FromStr for Day { type Err = ParseError; fn from_str(day: &str) -> Result<Self, Self::Err> { match day { "sunday" => Ok(Day::Sunday), "monday" => Ok(Day::Monday), _ => Err("Could not parse a day"), } } }
应该是字符串,将使用default_value
解释为Day
。
from_str
#[structopt(short = "d", long = "day", default_value = "monday")]
day: Day,
您可以按照消息提示通过为error[E0277]: the trait bound `Day: std::str::FromStr` is not satisfied --> src/main.rs:22:17 | 22 | #[derive(Debug, StructOpt)] | ^^^^^^^^^ the trait `std::str::FromStr` is not implemented for `Day` | = note: required by `std::str::FromStr::from_str`
实现FromStr
(请参见Day
)或为kennytm's answer定义解析函数来解决此问题:
Day
并使用fn parse_day(src: &str) -> Result<Day, String> { match src { "sunday" => Ok(Day::Sunday), "monday" => Ok(Day::Monday), _ => Err(format!("Invalid day: {}", src)) } }
属性指定它:
try_from_str
/// Day of the week
#[structopt(short = "d", long = "day", parse(try_from_str = "parse_day"), default_value = "monday")]
day: Day,
有效,但是@kennytm's approach宏是更简洁的方法,如arg_enum!
所示:这将使您将工作日解析为structopt
或arg_enum! { #[derive(Debug)] enum Day { Sunday, Monday } } #[derive(StructOpt, Debug)] struct Opt { /// Important argument. #[structopt(possible_values = &Day::variants(), case_insensitive = true)] i: Day, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); }
。