Skip to content

Commit

Permalink
Introduce #[structopt(external_subcommand)]
Browse files Browse the repository at this point in the history
  • Loading branch information
CreepySkeleton committed Dec 22, 2019
1 parent cf407a0 commit 838dde5
Show file tree
Hide file tree
Showing 7 changed files with 398 additions and 179 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
target
Cargo.lock
expanded.rs
*~

.idea/
Expand Down
17 changes: 5 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -972,22 +972,15 @@ pub trait StructOpt {
// ** SUBJECT TO CHANGE WITHOUT NOTICE!!! **

#[doc(hidden)]
fn is_subcommand() -> bool {
unimplemented!()
}
fn augment_clap<'a, 'b>(_app: clap::App<'a, 'b>) -> clap::App<'a, 'b>;

#[doc(hidden)]
fn augment_clap<'a, 'b>(_app: clap::App<'a, 'b>) -> clap::App<'a, 'b> {
unimplemented!()
}
fn subcommand_settings<'a, 'b>(_app: clap::App<'a, 'b>) -> clap::App<'a, 'b>;

#[doc(hidden)]
fn from_subcommand<'a, 'b>(_sub: (&'b str, Option<&'b clap::ArgMatches<'a>>)) -> Option<Self>
where
Self: Sized,
{
unimplemented!()
}
Self: Sized;
}

impl<T: StructOpt> StructOpt for Box<T> {
Expand All @@ -1005,8 +998,8 @@ impl<T: StructOpt> StructOpt for Box<T> {
}

#[doc(hidden)]
fn is_subcommand() -> bool {
<T as StructOpt>::is_subcommand()
fn subcommand_settings<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> {
<T as StructOpt>::subcommand_settings(app)
}

#[doc(hidden)]
Expand Down
23 changes: 18 additions & 5 deletions structopt-derive/src/attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use syn::{self, ext::IdentExt, spanned::Spanned, Attribute, Expr, Ident, LitStr,
#[derive(Clone)]
pub enum Kind {
Arg(Sp<Ty>),
ExternalSubcommand(Sp<Ty>),
Subcommand(Sp<Ty>),
FlattenStruct,
Skip(Option<Expr>),
Expand Down Expand Up @@ -266,11 +267,17 @@ impl Attrs {
}

Subcommand(ident) => {
let ty = Sp::call_site(Ty::Other);
let ty = Sp::call_site(Ty::Other); // will be patched later
let kind = Sp::new(Kind::Subcommand(ty), ident.span());
self.set_kind(kind);
}

ExternalSubcommand(ident) => {
let ty = Sp::call_site(Ty::Other); // will be patched later
let kind = Sp::new(Kind::ExternalSubcommand(ty), ident.span());
self.set_kind(kind);
}

Flatten(ident) => {
let kind = Sp::new(Kind::FlattenStruct, ident.span());
self.set_kind(kind);
Expand Down Expand Up @@ -361,10 +368,12 @@ impl Attrs {
);
}
match &*res.kind {
Kind::Subcommand(_) => abort!(res.kind.span(), "subcommand is only allowed on fields"),
Kind::FlattenStruct => abort!(res.kind.span(), "flatten is only allowed on fields"),
Kind::Skip(_) => abort!(res.kind.span(), "skip is only allowed on fields"),
Kind::Arg(_) => res,
Kind::Subcommand(_) => {
abort!(res.kind.span(), "`subcommand` is only allowed on fields")
}
Kind::FlattenStruct => abort!(res.kind.span(), "`flatten` is only allowed on fields"),
Kind::Skip(_) => abort!(res.kind.span(), "`skip` is only allowed on fields"),
Kind::Arg(_) | Kind::ExternalSubcommand(_) => res,
}
}

Expand Down Expand Up @@ -398,6 +407,10 @@ impl Attrs {
);
}
}
Kind::ExternalSubcommand(_) => abort!(
res.kind.span(),
"`external_subcommand` must be placed on an enum variant, not on field"
),
Kind::Subcommand(_) => {
if res.has_custom_parser {
abort!(
Expand Down
Loading

0 comments on commit 838dde5

Please sign in to comment.