簡體   English   中英

如何在 clap 中將數字或字符串作為 CLI 參數

[英]How to have number or string as a CLI argument in clap

我想要一個可以是數字或字符串的參數。 除了自己實現FromStr之外,不知道如何實現這一點。 這似乎是一個簡單的用例來處理,不確定要使用什么宏。
在這里,我希望 testapp_id 是數字或字符串。
我的目標是使用如下:
cargo run -- testapps status 3cargo run -- testapps status app4

#[derive(Parser, Debug)]
#[clap(author,version,about)]
enum Submodules {
    #[clap(subcommand)]
    Testapps(TestappsCommands)
}

#[derive(Subcommand, Debug)]
enum TestappsCommands {
    List,
    Status {
        #[clap(flatten)]
        testapp_id: NumberOrString
    },
}

#[derive(Debug)]
enum NumberOrString {
    Number(u32),
    Str(String),
}

我在想flatten是我可以使用的,但它仍然抱怨缺少FromStr的實現。
如果我只對testapp_id使用 u32 或 String 類型,它工作正常,為什么不兩者都使用?

不要為此使用flatten 相反,您需要為您的枚舉實現FromStr ,例如:

impl FromStr for NumberOrString {
    type Err = &'static str;    // The actual type doesn't matter since we never error, but it must implement `Display`
    fn from_str(s: &str) -> Result<Self, Self::Err>
    {
        Ok (s.parse::<u32>()
             .map (NumberOrString::Number)
             .unwrap_or_else (|_| NumberOrString::Str (s.to_string())))
    }
}

操場

Rust 中的一種常見方法是使用 generics 來解決問題。 您可以使您的字段類型特別接受該字段的泛型。

#[derive(Subcommand, Debug)]
enum TestappsCommands<T> {
    List,
    Status {
        #[clap(flatten)]
        testapp_id: T
    },
}

但這還不夠。 因為您現在有一個類型T而不是NumberOrString ,這並不能解決您的問題。

我不知道您是否只是為了使testapp_id接受數字和字符串而設計NumberOrString ,但是,如果您不需要它,您可能希望編寫一些bounds

邊界是在類型T上約束 generics 的一種方式,其中應用了一些限制。

你可以這樣寫,而不是使用你的枚舉:

use std::str::FromStr;

// ... your code...

#[derive(Subcommand, Debug)]
enum TestappsCommands<T: FromStr> {
    List,
    Status {
        #[clap(flatten)]
        testapp_id: T
    },
}

現在您的字段將僅包含已實現FromStr的任何類型T的值。

由於您要求同時接受數字或字符串, FromStr它已經在 Rust 中實現,用於“數字”的所有有符號和無符號變體。

您可以在文檔中更好地閱讀它: https://doc.rust-lang.org/std/str/trait.FromStr.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM