如何在Rust中的structopt中使用枚举?

问题描述 投票:2回答:3

我想使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") }
enums rust command-line-arguments structopt
3个回答
12
投票
Struct-opt接受实现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


5
投票
错误消息是:

#[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


1
投票
[/// 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!所示:

this example from structopt

这将使您将工作日解析为structoptarg_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);
}
© www.soinside.com 2019 - 2024. All rights reserved.