mirror of
https://github.com/clap-rs/clap
synced 2024-12-14 06:42:33 +00:00
fix(derive): Fix the problem where the build fails due to the ambiguous type of map
> This PR closes #490. Please refer to #490 for the detail of the problem. Let me know if you want to make `convert_type` a function. This is a port of https://github.com/TeXitoi/structopt/pull/491 This is part of #2809
This commit is contained in:
parent
5512c90380
commit
51c723a84f
2 changed files with 38 additions and 2 deletions
|
@ -542,6 +542,13 @@ fn gen_parsers(
|
|||
let flag = *attrs.parser().kind == ParserKind::FromFlag;
|
||||
let occurrences = *attrs.parser().kind == ParserKind::FromOccurrences;
|
||||
let name = attrs.cased_name();
|
||||
let convert_type = match **ty {
|
||||
Ty::Vec | Ty::Option => sub_type(&field.ty).unwrap_or(&field.ty),
|
||||
Ty::OptionOption | Ty::OptionVec => {
|
||||
sub_type(&field.ty).and_then(sub_type).unwrap_or(&field.ty)
|
||||
}
|
||||
_ => &field.ty,
|
||||
};
|
||||
// Use `quote!` to give this identifier the same hygiene
|
||||
// as the `arg_matches` parameter definition. This
|
||||
// allows us to refer to `arg_matches` within a `quote_spanned` block
|
||||
|
@ -584,7 +591,7 @@ fn gen_parsers(
|
|||
Ty::OptionVec => quote_spanned! { ty.span()=>
|
||||
if #arg_matches.is_present(#name) {
|
||||
Some(#arg_matches.#values_of(#name)
|
||||
.map(|v| v.map(#parse).collect())
|
||||
.map(|v| v.map::<#convert_type, _>(#parse).collect())
|
||||
.unwrap_or_else(Vec::new))
|
||||
} else {
|
||||
None
|
||||
|
@ -600,7 +607,7 @@ fn gen_parsers(
|
|||
|
||||
quote_spanned! { ty.span()=>
|
||||
#arg_matches.#values_of(#name)
|
||||
.map(|v| v.map(#parse).collect())
|
||||
.map(|v| v.map::<#convert_type, _>(#parse).collect())
|
||||
.unwrap_or_else(Vec::new)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,3 +76,32 @@ fn issue_324() {
|
|||
let help = get_long_help::<Opt>();
|
||||
assert!(help.contains("MY_VERSION"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_490() {
|
||||
use clap::Clap;
|
||||
use std::iter::FromIterator;
|
||||
use std::str::FromStr;
|
||||
|
||||
struct U16ish;
|
||||
impl FromStr for U16ish {
|
||||
type Err = ();
|
||||
fn from_str(_: &str) -> Result<Self, Self::Err> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
impl<'a> FromIterator<&'a U16ish> for Vec<u16> {
|
||||
fn from_iter<T: IntoIterator<Item = &'a U16ish>>(_: T) -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clap, Debug)]
|
||||
struct Opt {
|
||||
opt_vec: Vec<u16>,
|
||||
#[clap(long)]
|
||||
opt_opt_vec: Option<Vec<u16>>,
|
||||
}
|
||||
|
||||
// Assert that it compiles
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue