1// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
2// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
3// Ana Hobden (@hoverbear) <operator@hoverbear.org>
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10//
11// This work was derived from Structopt (https://github.com/TeXitoi/structopt)
12// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
13// MIT/Apache 2.0 license.
14
15use proc_macro2::{Span, TokenStream};
16use quote::quote;
17use syn::{Generics, Ident};
18
19use crate::item::Item;
20
21pub fn gen_for_struct(
22 item: &Item,
23 item_name: &Ident,
24 generics: &Generics,
25) -> Result<TokenStream, syn::Error> {
26 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
27
28 let name = item.cased_name();
29 let app_var = Ident::new("__clap_app", Span::call_site());
30
31 let tokens = quote! {
32 #[allow(
33 dead_code,
34 unreachable_code,
35 unused_variables,
36 unused_braces,
37 unused_qualifications,
38 )]
39 #[allow(
40 clippy::style,
41 clippy::complexity,
42 clippy::pedantic,
43 clippy::restriction,
44 clippy::perf,
45 clippy::deprecated,
46 clippy::nursery,
47 clippy::cargo,
48 clippy::suspicious_else_formatting,
49 clippy::almost_swapped,
50 )]
51 #[automatically_derived]
52 impl #impl_generics clap::CommandFactory for #item_name #ty_generics #where_clause {
53 fn command<'b>() -> clap::Command {
54 let #app_var = clap::Command::new(#name);
55 <Self as clap::Args>::augment_args(#app_var)
56 }
57
58 fn command_for_update<'b>() -> clap::Command {
59 let #app_var = clap::Command::new(#name);
60 <Self as clap::Args>::augment_args_for_update(#app_var)
61 }
62 }
63 };
64
65 Ok(tokens)
66}
67
68pub fn gen_for_enum(
69 item: &Item,
70 item_name: &Ident,
71 generics: &Generics,
72) -> Result<TokenStream, syn::Error> {
73 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
74
75 let name = item.cased_name();
76 let app_var = Ident::new("__clap_app", Span::call_site());
77
78 Ok(quote! {
79 #[allow(
80 dead_code,
81 unreachable_code,
82 unused_variables,
83 unused_braces,
84 unused_qualifications,
85 )]
86 #[allow(
87 clippy::style,
88 clippy::complexity,
89 clippy::pedantic,
90 clippy::restriction,
91 clippy::perf,
92 clippy::deprecated,
93 clippy::nursery,
94 clippy::cargo,
95 clippy::suspicious_else_formatting,
96 clippy::almost_swapped,
97 )]
98 #[automatically_derived]
99 impl #impl_generics clap::CommandFactory for #item_name #ty_generics #where_clause {
100 fn command<'b>() -> clap::Command {
101 let #app_var = clap::Command::new(#name)
102 .subcommand_required(true)
103 .arg_required_else_help(true);
104 <Self as clap::Subcommand>::augment_subcommands(#app_var)
105 }
106
107 fn command_for_update<'b>() -> clap::Command {
108 let #app_var = clap::Command::new(#name);
109 <Self as clap::Subcommand>::augment_subcommands_for_update(#app_var)
110 .subcommand_required(false)
111 .arg_required_else_help(false)
112 }
113 }
114 })
115}
116