Merge "Upgrade rust/crates/structopt-derive to 0.4.16" am: 6a8fd71e87 am: 5162c84530 am: 08b93b9202 am: 3ad58637ab am: e7e7f4dfc1
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/structopt-derive/+/1833387
Change-Id: I9e0344d62efc4c97da9f48004902ca239a08fd23
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 887fa2d..0057313 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
{
"git": {
- "sha1": "004cfc218e7fbfdbecc4088f9e3fa5061f36cb4d"
+ "sha1": "88e5402df017c052f1524f293b2e13bd01810819"
}
}
diff --git a/Android.bp b/Android.bp
index eec57d9..cd2b353 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,4 @@
-// This file is generated by cargo2android.py --run --tests --dependencies.
+// This file is generated by cargo2android.py --run --tests.
// Do not modify this file as changes will be overridden on upgrade.
package {
@@ -42,6 +42,8 @@
rust_proc_macro {
name: "libstructopt_derive",
crate_name: "structopt_derive",
+ cargo_env_compat: true,
+ cargo_pkg_version: "0.4.16",
srcs: ["src/lib.rs"],
edition: "2018",
rustlibs: [
@@ -56,6 +58,8 @@
rust_test_host {
name: "structopt-derive_host_test_src_lib",
crate_name: "structopt_derive",
+ cargo_env_compat: true,
+ cargo_pkg_version: "0.4.16",
srcs: ["src/lib.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -71,14 +75,3 @@
"libsyn",
],
}
-
-// dependent_library ["feature_list"]
-// heck-0.3.3
-// proc-macro-error-1.0.4 "default,syn,syn-error"
-// proc-macro-error-attr-1.0.4
-// proc-macro2-1.0.28 "default,proc-macro"
-// quote-1.0.9 "default,proc-macro"
-// syn-1.0.74 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote"
-// unicode-segmentation-1.8.0
-// unicode-xid-0.2.2 "default"
-// version_check-0.9.3
diff --git a/Cargo.toml b/Cargo.toml
index 6a9c2b1..7a10314 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "structopt-derive"
-version = "0.4.15"
+version = "0.4.16"
authors = ["Guillaume Pinot <[email protected]>"]
description = "Parse command line argument by defining a struct, derive crate."
documentation = "https://docs.rs/structopt-derive"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index db7e295..b41ac8a 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "structopt-derive"
-version = "0.4.15"
+version = "0.4.16"
edition = "2018"
authors = ["Guillaume Pinot <[email protected]>"]
description = "Parse command line argument by defining a struct, derive crate."
diff --git a/METADATA b/METADATA
index e5e5980..6f27d42 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/structopt-derive/structopt-derive-0.4.15.crate"
+ value: "https://static.crates.io/crates/structopt-derive/structopt-derive-0.4.16.crate"
}
- version: "0.4.15"
+ version: "0.4.16"
license_type: NOTICE
last_upgrade_date {
year: 2021
- month: 8
- day: 9
+ month: 9
+ day: 22
}
}
diff --git a/src/attrs.rs b/src/attrs.rs
index aa16145..35acd5a 100644
--- a/src/attrs.rs
+++ b/src/attrs.rs
@@ -405,6 +405,7 @@
parent_attrs: Option<&Attrs>,
argument_casing: Sp<CasingStyle>,
env_casing: Sp<CasingStyle>,
+ allow_skip: bool,
) -> Self {
let mut res = Self::new(span, name, parent_attrs, None, argument_casing, env_casing);
res.push_attrs(attrs);
@@ -418,8 +419,10 @@
}
match &*res.kind {
Kind::Subcommand(_) => abort!(res.kind.span(), "subcommand is only allowed on fields"),
- Kind::Skip(_) => abort!(res.kind.span(), "skip is only allowed on fields"),
- Kind::Arg(_) | Kind::ExternalSubcommand | Kind::Flatten => res,
+ Kind::Skip(_) if !allow_skip => {
+ abort!(res.kind.span(), "skip is only allowed on fields")
+ }
+ Kind::Arg(_) | Kind::ExternalSubcommand | Kind::Flatten | Kind::Skip(_) => res,
}
}
diff --git a/src/lib.rs b/src/lib.rs
index cf4dbba..b2835b4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -330,6 +330,13 @@
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,
+ };
let field_value = match **ty {
Ty::Bool => quote_spanned!(ty.span()=> #matches.is_present(#name)),
@@ -349,7 +356,7 @@
Ty::OptionVec => quote_spanned! { ty.span()=>
if #matches.is_present(#name) {
Some(#matches.#values_of(#name)
- .map_or_else(Vec::new, |v| v.map(#parse).collect()))
+ .map_or_else(Vec::new, |v| v.map::<#convert_type, _>(#parse).collect()))
} else {
None
}
@@ -357,7 +364,7 @@
Ty::Vec => quote_spanned! { ty.span()=>
#matches.#values_of(#name)
- .map_or_else(Vec::new, |v| v.map(#parse).collect())
+ .map_or_else(Vec::new, |v| v.map::<#convert_type, _>(#parse).collect())
},
Ty::Other if occurrences => quote_spanned! { ty.span()=>
@@ -409,6 +416,7 @@
None,
Sp::call_site(DEFAULT_CASING),
Sp::call_site(DEFAULT_ENV_CASING),
+ false,
);
let tokens = {
let name = attrs.cased_name();
@@ -471,7 +479,7 @@
) -> TokenStream {
use syn::Fields::*;
- let subcommands = variants.iter().map(|variant| {
+ let subcommands = variants.iter().filter_map(|variant| {
let attrs = Attrs::from_struct(
variant.span(),
&variant.attrs,
@@ -479,26 +487,29 @@
Some(parent_attribute),
parent_attribute.casing(),
parent_attribute.env_casing(),
+ true,
);
let kind = attrs.kind();
match &*kind {
+ Kind::Skip(_) => None,
+
Kind::ExternalSubcommand => {
let app_var = Ident::new("app", Span::call_site());
- quote_spanned! { attrs.kind().span()=>
+ Some(quote_spanned! { attrs.kind().span()=>
let #app_var = #app_var.setting(
::structopt::clap::AppSettings::AllowExternalSubcommands
);
- }
+ })
},
Kind::Flatten => {
match variant.fields {
Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
let ty = &unnamed[0];
- quote! {
+ Some(quote! {
let app = <#ty as ::structopt::StructOptInternal>::augment_clap(app);
- }
+ })
},
_ => abort!(
variant,
@@ -535,13 +546,13 @@
let name = attrs.cased_name();
let from_attrs = attrs.top_level_methods();
let version = attrs.version();
- quote! {
+ Some(quote! {
let app = app.subcommand({
let #app_var = ::structopt::clap::SubCommand::with_name(#name);
let #app_var = #arg_block;
#app_var#from_attrs#version
});
- }
+ })
},
}
});
@@ -588,58 +599,61 @@
Some(parent_attribute),
parent_attribute.casing(),
parent_attribute.env_casing(),
+ true,
);
let variant_name = &variant.ident;
- if let Kind::ExternalSubcommand = *attrs.kind() {
- if ext_subcmd.is_some() {
- abort!(
- attrs.kind().span(),
- "Only one variant can be marked with `external_subcommand`, \
+ match *attrs.kind() {
+ Kind::ExternalSubcommand => {
+ if ext_subcmd.is_some() {
+ abort!(
+ attrs.kind().span(),
+ "Only one variant can be marked with `external_subcommand`, \
this is the second"
- );
- }
-
- let ty = match variant.fields {
- Unnamed(ref fields) if fields.unnamed.len() == 1 => &fields.unnamed[0].ty,
-
- _ => abort!(
- variant,
- "The enum variant marked with `external_attribute` must be \
- a single-typed tuple, and the type must be either `Vec<String>` \
- or `Vec<OsString>`."
- ),
- };
-
- let (span, str_ty, values_of) = match subty_if_name(ty, "Vec") {
- Some(subty) => {
- if is_simple_ty(subty, "String") {
- (
- subty.span(),
- quote!(::std::string::String),
- quote!(values_of),
- )
- } else {
- (
- subty.span(),
- quote!(::std::ffi::OsString),
- quote!(values_of_os),
- )
- }
+ );
}
- None => abort!(
- ty,
- "The type must be either `Vec<String>` or `Vec<OsString>` \
- to be used with `external_subcommand`."
- ),
- };
+ let ty = match variant.fields {
+ Unnamed(ref fields) if fields.unnamed.len() == 1 => &fields.unnamed[0].ty,
- ext_subcmd = Some((span, variant_name, str_ty, values_of));
- None
- } else {
- Some((variant, attrs))
+ _ => abort!(
+ variant,
+ "The enum variant marked with `external_attribute` must be \
+ a single-typed tuple, and the type must be either `Vec<String>` \
+ or `Vec<OsString>`."
+ ),
+ };
+
+ let (span, str_ty, values_of) = match subty_if_name(ty, "Vec") {
+ Some(subty) => {
+ if is_simple_ty(subty, "String") {
+ (
+ subty.span(),
+ quote!(::std::string::String),
+ quote!(values_of),
+ )
+ } else {
+ (
+ subty.span(),
+ quote!(::std::ffi::OsString),
+ quote!(values_of_os),
+ )
+ }
+ }
+
+ None => abort!(
+ ty,
+ "The type must be either `Vec<String>` or `Vec<OsString>` \
+ to be used with `external_subcommand`."
+ ),
+ };
+
+ ext_subcmd = Some((span, variant_name, str_ty, values_of));
+ None
+ }
+ Kind::Skip(_) => None,
+ _ => Some((variant, attrs)),
}
})
.partition(|(_, attrs)| match &*attrs.kind() {
@@ -736,7 +750,12 @@
}
#[cfg(feature = "paw")]
-fn gen_paw_impl(impl_generics: &ImplGenerics, name: &Ident, ty_generics: &TypeGenerics, where_clause: &TokenStream) -> TokenStream {
+fn gen_paw_impl(
+ impl_generics: &ImplGenerics,
+ name: &Ident,
+ ty_generics: &TypeGenerics,
+ where_clause: &TokenStream,
+) -> TokenStream {
quote! {
impl #impl_generics ::structopt::paw::ParseArgs for #name #ty_generics #where_clause {
type Error = std::io::Error;
@@ -752,8 +771,10 @@
TokenStream::new()
}
-fn split_structopt_generics_for_impl(generics: &Generics) -> (ImplGenerics, TypeGenerics, TokenStream) {
- use syn::{ token::Add, TypeParamBound::Trait };
+fn split_structopt_generics_for_impl(
+ generics: &Generics,
+) -> (ImplGenerics, TypeGenerics, TokenStream) {
+ use syn::{token::Add, TypeParamBound::Trait};
fn path_ends_with(path: &Path, ident: &str) -> bool {
path.segments.last().unwrap().ident == ident
@@ -770,7 +791,7 @@
return false;
}
- struct TraitBoundAmendments{
+ struct TraitBoundAmendments {
tokens: TokenStream,
need_where: bool,
need_comma: bool,
@@ -779,7 +800,7 @@
impl TraitBoundAmendments {
fn new(where_clause: Option<&WhereClause>) -> Self {
let tokens = TokenStream::new();
- let (need_where,need_comma) = if let Some(where_clause) = where_clause {
+ let (need_where, need_comma) = if let Some(where_clause) = where_clause {
if where_clause.predicates.trailing_punct() {
(false, false)
} else {
@@ -788,16 +809,20 @@
} else {
(true, false)
};
- Self{tokens, need_where, need_comma}
+ Self {
+ tokens,
+ need_where,
+ need_comma,
+ }
}
fn add(&mut self, amendment: TokenStream) {
if self.need_where {
- self.tokens.extend(quote!{ where });
+ self.tokens.extend(quote! { where });
self.need_where = false;
}
if self.need_comma {
- self.tokens.extend(quote!{ , });
+ self.tokens.extend(quote! { , });
}
self.tokens.extend(amendment);
self.need_comma = true;
@@ -814,7 +839,8 @@
if let GenericParam::Type(param) = param {
let param_ident = ¶m.ident;
if type_param_bounds_contains(¶m.bounds, "StructOpt") {
- trait_bound_amendments.add(quote!{ #param_ident : ::structopt::StructOptInternal });
+ trait_bound_amendments
+ .add(quote! { #param_ident : ::structopt::StructOptInternal });
}
}
}
@@ -824,7 +850,8 @@
if let WherePredicate::Type(predicate) = predicate {
let predicate_bounded_ty = &predicate.bounded_ty;
if type_param_bounds_contains(&predicate.bounds, "StructOpt") {
- trait_bound_amendments.add(quote!{ #predicate_bounded_ty : ::structopt::StructOptInternal });
+ trait_bound_amendments
+ .add(quote! { #predicate_bounded_ty : ::structopt::StructOptInternal });
}
}
}
@@ -834,7 +861,7 @@
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
- let where_clause = quote!{ #where_clause #trait_bound_amendments };
+ let where_clause = quote! { #where_clause #trait_bound_amendments };
(impl_generics, ty_generics, where_clause)
}
@@ -902,7 +929,6 @@
attrs: &[Attribute],
generics: &Generics,
) -> TokenStream {
-
let (impl_generics, ty_generics, where_clause) = split_structopt_generics_for_impl(&generics);
let basic_clap_app_gen = gen_clap_enum(attrs);
@@ -980,7 +1006,9 @@
fields: syn::Fields::Named(ref fields),
..
}) => impl_structopt_for_struct(struct_name, &fields.named, &input.attrs, &input.generics),
- Enum(ref e) => impl_structopt_for_enum(struct_name, &e.variants, &input.attrs, &input.generics),
+ Enum(ref e) => {
+ impl_structopt_for_enum(struct_name, &e.variants, &input.attrs, &input.generics)
+ }
_ => abort_call_site!("structopt only supports non-tuple structs and enums"),
}
}