[英]How to have number or string as a CLI argument in clap
我想要一個可以是數字或字符串的參數。 除了自己實現FromStr
之外,不知道如何實現這一點。 這似乎是一個簡單的用例來處理,不確定要使用什么宏。
在這里,我希望 testapp_id 是數字或字符串。
我的目標是使用如下:
cargo run -- testapps status 3
或cargo 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.