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 clippy::redundant_locals,
51 )]
52 #[automatically_derived]
53 impl #impl_generics clap::CommandFactory for #item_name #ty_generics #where_clause {
54 fn command<'b>() -> clap::Command {
55 let #app_var = clap::Command::new(#name);
56 <Self as clap::Args>::augment_args(#app_var)
57 }
58
59 fn command_for_update<'b>() -> clap::Command {
60 let #app_var = clap::Command::new(#name);
61 <Self as clap::Args>::augment_args_for_update(#app_var)
62 }
63 }
64 };
65
66 Ok(tokens)
67}
68
69pub fn gen_for_enum(
70 item: &Item,
71 item_name: &Ident,
72 generics: &Generics,
73) -> Result<TokenStream, syn::Error> {
74 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
75
76 let name = item.cased_name();
77 let app_var = Ident::new("__clap_app", Span::call_site());
78
79 Ok(quote! {
80 #[allow(
81 dead_code,
82 unreachable_code,
83 unused_variables,
84 unused_braces,
85 unused_qualifications,
86 )]
87 #[allow(
88 clippy::style,
89 clippy::complexity,
90 clippy::pedantic,
91 clippy::restriction,
92 clippy::perf,
93 clippy::deprecated,
94 clippy::nursery,
95 clippy::cargo,
96 clippy::suspicious_else_formatting,
97 clippy::almost_swapped,
98 clippy::redundant_locals,
99 )]
100 #[automatically_derived]
101 impl #impl_generics clap::CommandFactory for #item_name #ty_generics #where_clause {
102 fn command<'b>() -> clap::Command {
103 let #app_var = clap::Command::new(#name)
104 .subcommand_required(true)
105 .arg_required_else_help(true);
106 <Self as clap::Subcommand>::augment_subcommands(#app_var)
107 }
108
109 fn command_for_update<'b>() -> clap::Command {
110 let #app_var = clap::Command::new(#name);
111 <Self as clap::Subcommand>::augment_subcommands_for_update(#app_var)
112 .subcommand_required(false)
113 .arg_required_else_help(false)
114 }
115 }
116 })
117}
118