Created
May 19, 2021 18:32
-
-
Save felipesere/0c4d4119096a4ae45f19287d4a53bf7e to your computer and use it in GitHub Desktop.
Example using clap_derive and its expansion.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use clap::Clap; | |
#[derive(Debug, PartialEq, Clap)] | |
struct Opt { | |
#[clap(global = true, long)] | |
global: bool, | |
#[clap(subcommand)] | |
sub: Subcommands, | |
} | |
#[derive(Debug, PartialEq, Clap)] | |
enum Subcommands { | |
Add, | |
Remove, | |
Global(GlobalCmd), | |
#[clap(external_subcommand)] | |
Other(Vec<String>), | |
} | |
#[derive(Debug, PartialEq, Clap)] | |
struct GlobalCmd { | |
#[clap(from_global)] | |
global: bool, | |
} | |
fn main() { | |
let opt = Opt::parse(); | |
println!("{:?}", opt); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(prelude_import)] | |
#[prelude_import] | |
use std::prelude::rust_2018::*; | |
#[macro_use] | |
extern crate std; | |
use clap::Clap; | |
struct Opt { | |
#[clap(global = true, long)] | |
global: bool, | |
#[clap(subcommand)] | |
sub: Subcommands, | |
} | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::core::fmt::Debug for Opt { | |
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { | |
match *self { | |
Opt { | |
global: ref __self_0_0, | |
sub: ref __self_0_1, | |
} => { | |
let debug_trait_builder = &mut ::core::fmt::Formatter::debug_struct(f, "Opt"); | |
let _ = | |
::core::fmt::DebugStruct::field(debug_trait_builder, "global", &&(*__self_0_0)); | |
let _ = | |
::core::fmt::DebugStruct::field(debug_trait_builder, "sub", &&(*__self_0_1)); | |
::core::fmt::DebugStruct::finish(debug_trait_builder) | |
} | |
} | |
} | |
} | |
impl ::core::marker::StructuralPartialEq for Opt {} | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::core::cmp::PartialEq for Opt { | |
#[inline] | |
fn eq(&self, other: &Opt) -> bool { | |
match *other { | |
Opt { | |
global: ref __self_1_0, | |
sub: ref __self_1_1, | |
} => match *self { | |
Opt { | |
global: ref __self_0_0, | |
sub: ref __self_0_1, | |
} => (*__self_0_0) == (*__self_1_0) && (*__self_0_1) == (*__self_1_1), | |
}, | |
} | |
} | |
#[inline] | |
fn ne(&self, other: &Opt) -> bool { | |
match *other { | |
Opt { | |
global: ref __self_1_0, | |
sub: ref __self_1_1, | |
} => match *self { | |
Opt { | |
global: ref __self_0_0, | |
sub: ref __self_0_1, | |
} => (*__self_0_0) != (*__self_1_0) || (*__self_0_1) != (*__self_1_1), | |
}, | |
} | |
} | |
} | |
impl clap::Clap for Opt {} | |
#[allow(dead_code, unreachable_code, unused_variables)] | |
#[allow( | |
clippy::style, | |
clippy::complexity, | |
clippy::pedantic, | |
clippy::restriction, | |
clippy::perf, | |
clippy::deprecated, | |
clippy::nursery, | |
clippy::cargo | |
)] | |
#[deny(clippy::correctness)] | |
impl clap::IntoApp for Opt { | |
fn into_app<'b>() -> clap::App<'b> { | |
Self::augment_clap(clap::App::new("clap_derive")) | |
} | |
fn into_app_for_update<'b>() -> clap::App<'b> { | |
Self::augment_clap_for_update(clap::App::new("clap_derive")) | |
} | |
fn augment_clap<'b>(app: clap::App<'b>) -> clap::App<'b> { | |
{ | |
let app = app; | |
let app = app.arg(clap::Arg::new("global").global(true).long("global")); | |
let app = <Subcommands as clap::Subcommand>::augment_subcommands(app); | |
let app = app.setting(clap::AppSettings::SubcommandRequiredElseHelp); | |
app | |
} | |
} | |
fn augment_clap_for_update<'b>(app: clap::App<'b>) -> clap::App<'b> { | |
{ | |
let app = app; | |
let app = app.arg(clap::Arg::new("global").global(true).long("global")); | |
let app = <Subcommands as clap::Subcommand>::augment_subcommands_for_update(app); | |
app | |
} | |
} | |
} | |
#[allow(dead_code, unreachable_code, unused_variables)] | |
#[allow( | |
clippy::style, | |
clippy::complexity, | |
clippy::pedantic, | |
clippy::restriction, | |
clippy::perf, | |
clippy::deprecated, | |
clippy::nursery, | |
clippy::cargo | |
)] | |
#[deny(clippy::correctness)] | |
impl clap::FromArgMatches for Opt { | |
fn from_arg_matches(arg_matches: &clap::ArgMatches) -> Self { | |
Opt { | |
global: arg_matches.is_present("global"), | |
sub: { | |
<Subcommands as clap::Subcommand>::from_subcommand(arg_matches.subcommand()) | |
.unwrap() | |
}, | |
} | |
} | |
fn update_from_arg_matches(&mut self, arg_matches: &clap::ArgMatches) { | |
if arg_matches.is_present("global") { | |
#[allow(non_snake_case)] | |
let global = &mut self.global; | |
*global = *global || arg_matches.is_present("global") | |
} | |
{ | |
#[allow(non_snake_case)] | |
let sub = &mut self.sub; | |
<Subcommands as clap::Subcommand>::update_from_subcommand( | |
sub, | |
arg_matches.subcommand(), | |
); | |
} | |
} | |
} | |
enum Subcommands { | |
Add, | |
Remove, | |
Global(GlobalCmd), | |
#[clap(external_subcommand)] | |
Other(Vec<String>), | |
} | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::core::fmt::Debug for Subcommands { | |
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { | |
match (&*self,) { | |
(&Subcommands::Add,) => { | |
let debug_trait_builder = &mut ::core::fmt::Formatter::debug_tuple(f, "Add"); | |
::core::fmt::DebugTuple::finish(debug_trait_builder) | |
} | |
(&Subcommands::Remove,) => { | |
let debug_trait_builder = &mut ::core::fmt::Formatter::debug_tuple(f, "Remove"); | |
::core::fmt::DebugTuple::finish(debug_trait_builder) | |
} | |
(&Subcommands::Global(ref __self_0),) => { | |
let debug_trait_builder = &mut ::core::fmt::Formatter::debug_tuple(f, "Global"); | |
let _ = ::core::fmt::DebugTuple::field(debug_trait_builder, &&(*__self_0)); | |
::core::fmt::DebugTuple::finish(debug_trait_builder) | |
} | |
(&Subcommands::Other(ref __self_0),) => { | |
let debug_trait_builder = &mut ::core::fmt::Formatter::debug_tuple(f, "Other"); | |
let _ = ::core::fmt::DebugTuple::field(debug_trait_builder, &&(*__self_0)); | |
::core::fmt::DebugTuple::finish(debug_trait_builder) | |
} | |
} | |
} | |
} | |
impl ::core::marker::StructuralPartialEq for Subcommands {} | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::core::cmp::PartialEq for Subcommands { | |
#[inline] | |
fn eq(&self, other: &Subcommands) -> bool { | |
{ | |
let __self_vi = ::core::intrinsics::discriminant_value(&*self); | |
let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other); | |
if true && __self_vi == __arg_1_vi { | |
match (&*self, &*other) { | |
(&Subcommands::Global(ref __self_0), &Subcommands::Global(ref __arg_1_0)) => { | |
(*__self_0) == (*__arg_1_0) | |
} | |
(&Subcommands::Other(ref __self_0), &Subcommands::Other(ref __arg_1_0)) => { | |
(*__self_0) == (*__arg_1_0) | |
} | |
_ => true, | |
} | |
} else { | |
false | |
} | |
} | |
} | |
#[inline] | |
fn ne(&self, other: &Subcommands) -> bool { | |
{ | |
let __self_vi = ::core::intrinsics::discriminant_value(&*self); | |
let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other); | |
if true && __self_vi == __arg_1_vi { | |
match (&*self, &*other) { | |
(&Subcommands::Global(ref __self_0), &Subcommands::Global(ref __arg_1_0)) => { | |
(*__self_0) != (*__arg_1_0) | |
} | |
(&Subcommands::Other(ref __self_0), &Subcommands::Other(ref __arg_1_0)) => { | |
(*__self_0) != (*__arg_1_0) | |
} | |
_ => false, | |
} | |
} else { | |
true | |
} | |
} | |
} | |
} | |
impl clap::Clap for Subcommands {} | |
#[allow(dead_code, unreachable_code, unused_variables)] | |
#[allow( | |
clippy::style, | |
clippy::complexity, | |
clippy::pedantic, | |
clippy::restriction, | |
clippy::perf, | |
clippy::deprecated, | |
clippy::nursery, | |
clippy::cargo | |
)] | |
#[deny(clippy::correctness)] | |
impl clap::IntoApp for Subcommands { | |
fn into_app<'b>() -> clap::App<'b> { | |
let app = | |
clap::App::new("clap_derive").setting(clap::AppSettings::SubcommandRequiredElseHelp); | |
<Subcommands as clap::IntoApp>::augment_clap(app) | |
} | |
fn augment_clap<'b>(app: clap::App<'b>) -> clap::App<'b> { | |
<Subcommands as clap::Subcommand>::augment_subcommands(app) | |
} | |
fn into_app_for_update<'b>() -> clap::App<'b> { | |
let app = clap::App::new("clap_derive"); | |
<Subcommands as clap::IntoApp>::augment_clap_for_update(app) | |
} | |
fn augment_clap_for_update<'b>(app: clap::App<'b>) -> clap::App<'b> { | |
<Subcommands as clap::Subcommand>::augment_subcommands_for_update(app) | |
} | |
} | |
#[allow(dead_code, unreachable_code, unused_variables)] | |
#[allow( | |
clippy::style, | |
clippy::complexity, | |
clippy::pedantic, | |
clippy::restriction, | |
clippy::perf, | |
clippy::deprecated, | |
clippy::nursery, | |
clippy::cargo | |
)] | |
#[deny(clippy::correctness)] | |
impl clap::FromArgMatches for Subcommands { | |
fn from_arg_matches(arg_matches: &clap::ArgMatches) -> Self { | |
<Subcommands as clap::Subcommand>::from_subcommand(arg_matches.subcommand()).unwrap() | |
} | |
fn update_from_arg_matches(&mut self, arg_matches: &clap::ArgMatches) { | |
<Subcommands as clap::Subcommand>::update_from_subcommand(self, arg_matches.subcommand()); | |
} | |
} | |
#[allow(dead_code, unreachable_code, unused_variables)] | |
#[allow( | |
clippy::style, | |
clippy::complexity, | |
clippy::pedantic, | |
clippy::restriction, | |
clippy::perf, | |
clippy::deprecated, | |
clippy::nursery, | |
clippy::cargo | |
)] | |
#[deny(clippy::correctness)] | |
impl clap::Subcommand for Subcommands { | |
fn augment_subcommands<'b>(app: clap::App<'b>) -> clap::App<'b> { | |
let app = app; | |
let app = app.subcommand({ | |
let subcommand = clap::App::new("add"); | |
let subcommand = subcommand; | |
subcommand | |
}); | |
let app = app.subcommand({ | |
let subcommand = clap::App::new("remove"); | |
let subcommand = subcommand; | |
subcommand | |
}); | |
let app = app.subcommand({ | |
let subcommand = clap::App::new("global"); | |
let subcommand = { <GlobalCmd as clap::IntoApp>::augment_clap(subcommand) }; | |
subcommand | |
}); | |
let app = app.setting(clap::AppSettings::AllowExternalSubcommands); | |
app | |
} | |
fn from_subcommand(subcommand: Option<(&str, &clap::ArgMatches)>) -> Option<Self> { | |
match subcommand { | |
Some(("add", arg_matches)) => Some(Subcommands::Add), | |
Some(("remove", arg_matches)) => Some(Subcommands::Remove), | |
Some(("global", arg_matches)) => Some(Subcommands::Global( | |
<GlobalCmd as clap::FromArgMatches>::from_arg_matches(arg_matches), | |
)), | |
other => match other { | |
None => ::std::option::Option::None, | |
Some((external, arg_matches)) => ::std::option::Option::Some(Subcommands::Other( | |
::std::iter::once(::std::string::String::from(external)) | |
.chain( | |
arg_matches | |
.values_of("") | |
.into_iter() | |
.flatten() | |
.map(::std::string::String::from), | |
) | |
.collect::<::std::vec::Vec<_>>(), | |
)), | |
}, | |
} | |
} | |
fn augment_subcommands_for_update<'b>(app: clap::App<'b>) -> clap::App<'b> { | |
let app = app; | |
let app = app.subcommand({ | |
let subcommand = clap::App::new("add"); | |
let subcommand = subcommand; | |
subcommand | |
}); | |
let app = app.subcommand({ | |
let subcommand = clap::App::new("remove"); | |
let subcommand = subcommand; | |
subcommand | |
}); | |
let app = app.subcommand({ | |
let subcommand = clap::App::new("global"); | |
let subcommand = { <GlobalCmd as clap::IntoApp>::augment_clap(subcommand) }; | |
subcommand | |
}); | |
let app = app.setting(clap::AppSettings::AllowExternalSubcommands); | |
app | |
} | |
fn update_from_subcommand<'b>(&mut self, subcommand: Option<(&str, &clap::ArgMatches)>) { | |
if let Some((name, arg_matches)) = subcommand { | |
match (name, self) { | |
("add", Subcommands::Add) => {} | |
("remove", Subcommands::Remove) => {} | |
("global", Subcommands::Global(ref mut arg)) => { | |
clap::FromArgMatches::update_from_arg_matches(arg, arg_matches) | |
} | |
(_, s) => { | |
if let Some(sub) = | |
<Self as clap::Subcommand>::from_subcommand(Some((name, arg_matches))) | |
{ | |
*s = sub; | |
} | |
} | |
} | |
} | |
} | |
} | |
struct GlobalCmd { | |
#[clap(from_global)] | |
global: bool, | |
} | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::core::fmt::Debug for GlobalCmd { | |
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { | |
match *self { | |
GlobalCmd { | |
global: ref __self_0_0, | |
} => { | |
let debug_trait_builder = &mut ::core::fmt::Formatter::debug_struct(f, "GlobalCmd"); | |
let _ = | |
::core::fmt::DebugStruct::field(debug_trait_builder, "global", &&(*__self_0_0)); | |
::core::fmt::DebugStruct::finish(debug_trait_builder) | |
} | |
} | |
} | |
} | |
impl ::core::marker::StructuralPartialEq for GlobalCmd {} | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::core::cmp::PartialEq for GlobalCmd { | |
#[inline] | |
fn eq(&self, other: &GlobalCmd) -> bool { | |
match *other { | |
GlobalCmd { | |
global: ref __self_1_0, | |
} => match *self { | |
GlobalCmd { | |
global: ref __self_0_0, | |
} => (*__self_0_0) == (*__self_1_0), | |
}, | |
} | |
} | |
#[inline] | |
fn ne(&self, other: &GlobalCmd) -> bool { | |
match *other { | |
GlobalCmd { | |
global: ref __self_1_0, | |
} => match *self { | |
GlobalCmd { | |
global: ref __self_0_0, | |
} => (*__self_0_0) != (*__self_1_0), | |
}, | |
} | |
} | |
} | |
impl clap::Clap for GlobalCmd {} | |
#[allow(dead_code, unreachable_code, unused_variables)] | |
#[allow( | |
clippy::style, | |
clippy::complexity, | |
clippy::pedantic, | |
clippy::restriction, | |
clippy::perf, | |
clippy::deprecated, | |
clippy::nursery, | |
clippy::cargo | |
)] | |
#[deny(clippy::correctness)] | |
impl clap::IntoApp for GlobalCmd { | |
fn into_app<'b>() -> clap::App<'b> { | |
Self::augment_clap(clap::App::new("clap_derive")) | |
} | |
fn into_app_for_update<'b>() -> clap::App<'b> { | |
Self::augment_clap_for_update(clap::App::new("clap_derive")) | |
} | |
fn augment_clap<'b>(app: clap::App<'b>) -> clap::App<'b> { | |
{ | |
let app = app; | |
app | |
} | |
} | |
fn augment_clap_for_update<'b>(app: clap::App<'b>) -> clap::App<'b> { | |
{ | |
let app = app; | |
app | |
} | |
} | |
} | |
#[allow(dead_code, unreachable_code, unused_variables)] | |
#[allow( | |
clippy::style, | |
clippy::complexity, | |
clippy::pedantic, | |
clippy::restriction, | |
clippy::perf, | |
clippy::deprecated, | |
clippy::nursery, | |
clippy::cargo | |
)] | |
#[deny(clippy::correctness)] | |
impl clap::FromArgMatches for GlobalCmd { | |
fn from_arg_matches(arg_matches: &clap::ArgMatches) -> Self { | |
GlobalCmd { | |
global: arg_matches.is_present("global"), | |
} | |
} | |
fn update_from_arg_matches(&mut self, arg_matches: &clap::ArgMatches) { | |
if arg_matches.is_present("global") { | |
#[allow(non_snake_case)] | |
let global = &mut self.global; | |
*global = *global || arg_matches.is_present("global") | |
} | |
} | |
} | |
fn main() { | |
let opt = Opt::parse(); | |
{ | |
::std::io::_print(::core::fmt::Arguments::new_v1( | |
&["", "\n"], | |
&match (&opt,) { | |
(arg0,) => [::core::fmt::ArgumentV1::new(arg0, ::core::fmt::Debug::fmt)], | |
}, | |
)); | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment