refactor(derive): Delay error handling

This commit is contained in:
Ed Page 2022-09-06 07:10:38 -05:00
parent f9e1ba2c1e
commit b29f3ff22f
5 changed files with 29 additions and 52 deletions

View file

@ -370,13 +370,22 @@ pub fn gen_constructor(fields: &[(&Field, Item)]) -> TokenStream {
}
}
},
_ => {
Ty::Vec |
Ty::Other => {
quote_spanned! { kind.span()=>
#field_name: {
<#subcmd_type as clap::FromArgMatches>::from_arg_matches_mut(#arg_matches)?
}
}
},
Ty::OptionOption |
Ty::OptionVec => {
abort!(
ty.span(),
"{} types are not supported for subcommand",
ty.as_str()
);
}
}
}

View file

@ -126,38 +126,12 @@ impl Item {
Kind::Subcommand(_) => {
use syn::Fields::*;
use syn::FieldsUnnamed;
let field_ty = match variant.fields {
Named(_) => {
abort!(variant.span(), "structs are not allowed for subcommand");
}
Unit => abort!(variant.span(), "unit-type is not allowed for subcommand"),
let ty = match variant.fields {
Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
&unnamed[0].ty
}
Unnamed(..) => {
abort!(
variant,
"non single-typed tuple is not allowed for subcommand"
)
Ty::from_syn_ty(&unnamed[0].ty)
}
Named(_) | Unnamed(..) | Unit => Sp::new(Ty::Other, span),
};
let ty = Ty::from_syn_ty(field_ty);
match *ty {
Ty::OptionOption => {
abort!(
field_ty,
"Option<Option<T>> type is not allowed for subcommand"
);
}
Ty::OptionVec => {
abort!(
field_ty,
"Option<Vec<T>> type is not allowed for subcommand"
);
}
_ => (),
}
res.kind = Sp::new(Kind::Subcommand(ty), res.kind.span());
}
@ -236,22 +210,6 @@ impl Item {
}
let ty = Ty::from_syn_ty(&field.ty);
match *ty {
Ty::OptionOption => {
abort!(
field.ty,
"Option<Option<T>> type is not allowed for subcommand"
);
}
Ty::OptionVec => {
abort!(
field.ty,
"Option<Vec<T>> type is not allowed for subcommand"
);
}
_ => (),
}
res.kind = Sp::new(Kind::Subcommand(ty), res.kind.span());
}
Kind::Skip(_, _) => {

View file

@ -35,6 +35,16 @@ impl Ty {
t(Other)
}
}
pub fn as_str(&self) -> &'static str {
match self {
Self::Vec => "Vec<T>",
Self::Option => "Option<T>",
Self::OptionOption => "Option<Option<T>>",
Self::OptionVec => "Option<Vec<T>>",
Self::Other => "...other...",
}
}
}
pub fn inner_type(field_ty: &syn::Type) -> &syn::Type {

View file

@ -1,5 +1,5 @@
error: Option<Option<T>> type is not allowed for subcommand
--> $DIR/subcommand_opt_opt.rs:17:10
error: Option<Option<T>> types are not supported for subcommand
--> tests/derive_ui/subcommand_opt_opt.rs:17:10
|
17 | cmd: Option<Option<Command>>,
| ^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^

View file

@ -1,5 +1,5 @@
error: Option<Vec<T>> type is not allowed for subcommand
--> $DIR/subcommand_opt_vec.rs:17:10
error: Option<Vec<T>> types are not supported for subcommand
--> tests/derive_ui/subcommand_opt_vec.rs:17:10
|
17 | cmd: Option<Vec<Command>>,
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^