Как я могу использовать перечисления в structopt в Rust? - PullRequest
0 голосов
/ 14 февраля 2019

Я бы хотел, чтобы 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);
}

Мой текущий лучший решение заключается в использовании 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")
}

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Сообщение об ошибке:

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 ), как предлагается в сообщении, или с помощьюопределение функции разбора для 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,
0 голосов
/ 14 февраля 2019

Struct-opt принимает любой тип, который реализует 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,
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...