1 // Copyright 2018 Guillaume Pinot (@TeXitoi) <[email protected]>,
2 // Kevin Knapp (@kbknapp) <[email protected]>, and
3 // Ana Hobden (@hoverbear) <[email protected]>
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 
15 use proc_macro2::{Ident, Span, TokenStream};
16 use quote::{format_ident, quote, quote_spanned};
17 use syn::{spanned::Spanned, Data, DeriveInput, FieldsUnnamed, Generics, Variant};
18 
19 use crate::derives::args;
20 use crate::derives::args::collect_args_fields;
21 use crate::item::{Item, Kind, Name};
22 use crate::utils::{is_simple_ty, subty_if_name};
23 
derive_subcommand(input: &DeriveInput) -> Result<TokenStream, syn::Error>24 pub fn derive_subcommand(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
25     let ident = &input.ident;
26 
27     match input.data {
28         Data::Enum(ref e) => {
29             let name = Name::Derived(ident.clone());
30             let item = Item::from_subcommand_enum(input, name)?;
31             let variants = e
32                 .variants
33                 .iter()
34                 .map(|variant| {
35                     let item =
36                         Item::from_subcommand_variant(variant, item.casing(), item.env_casing())?;
37                     Ok((variant, item))
38                 })
39                 .collect::<Result<Vec<_>, syn::Error>>()?;
40             gen_for_enum(&item, ident, &input.generics, &variants)
41         }
42         _ => abort_call_site!("`#[derive(Subcommand)]` only supports enums"),
43     }
44 }
45 
gen_for_enum( item: &Item, item_name: &Ident, generics: &Generics, variants: &[(&Variant, Item)], ) -> Result<TokenStream, syn::Error>46 pub fn gen_for_enum(
47     item: &Item,
48     item_name: &Ident,
49     generics: &Generics,
50     variants: &[(&Variant, Item)],
51 ) -> Result<TokenStream, syn::Error> {
52     if !matches!(&*item.kind(), Kind::Command(_)) {
53         abort! { item.kind().span(),
54             "`{}` cannot be used with `command`",
55             item.kind().name(),
56         }
57     }
58 
59     let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
60 
61     let from_arg_matches = gen_from_arg_matches(variants)?;
62     let update_from_arg_matches = gen_update_from_arg_matches(variants)?;
63 
64     let augmentation = gen_augment(variants, item, false)?;
65     let augmentation_update = gen_augment(variants, item, true)?;
66     let has_subcommand = gen_has_subcommand(variants)?;
67 
68     Ok(quote! {
69         #[allow(
70             dead_code,
71             unreachable_code,
72             unused_variables,
73             unused_braces,
74             unused_qualifications,
75         )]
76         #[allow(
77             clippy::style,
78             clippy::complexity,
79             clippy::pedantic,
80             clippy::restriction,
81             clippy::perf,
82             clippy::deprecated,
83             clippy::nursery,
84             clippy::cargo,
85             clippy::suspicious_else_formatting,
86             clippy::almost_swapped,
87             clippy::redundant_locals,
88         )]
89         #[automatically_derived]
90         impl #impl_generics clap::FromArgMatches for #item_name #ty_generics #where_clause {
91             fn from_arg_matches(__clap_arg_matches: &clap::ArgMatches) -> ::std::result::Result<Self, clap::Error> {
92                 Self::from_arg_matches_mut(&mut __clap_arg_matches.clone())
93             }
94 
95             #from_arg_matches
96 
97             fn update_from_arg_matches(&mut self, __clap_arg_matches: &clap::ArgMatches) -> ::std::result::Result<(), clap::Error> {
98                 self.update_from_arg_matches_mut(&mut __clap_arg_matches.clone())
99             }
100             #update_from_arg_matches
101         }
102 
103         #[allow(
104             dead_code,
105             unreachable_code,
106             unused_variables,
107             unused_braces,
108             unused_qualifications,
109         )]
110         #[allow(
111             clippy::style,
112             clippy::complexity,
113             clippy::pedantic,
114             clippy::restriction,
115             clippy::perf,
116             clippy::deprecated,
117             clippy::nursery,
118             clippy::cargo,
119             clippy::suspicious_else_formatting,
120             clippy::almost_swapped,
121             clippy::redundant_locals,
122         )]
123         #[automatically_derived]
124         impl #impl_generics clap::Subcommand for #item_name #ty_generics #where_clause {
125             fn augment_subcommands <'b>(__clap_app: clap::Command) -> clap::Command {
126                 #augmentation
127             }
128             fn augment_subcommands_for_update <'b>(__clap_app: clap::Command) -> clap::Command {
129                 #augmentation_update
130             }
131             fn has_subcommand(__clap_name: &str) -> bool {
132                 #has_subcommand
133             }
134         }
135     })
136 }
137 
gen_augment( variants: &[(&Variant, Item)], parent_item: &Item, override_required: bool, ) -> Result<TokenStream, syn::Error>138 fn gen_augment(
139     variants: &[(&Variant, Item)],
140     parent_item: &Item,
141     override_required: bool,
142 ) -> Result<TokenStream, syn::Error> {
143     use syn::Fields::*;
144 
145     let app_var = Ident::new("__clap_app", Span::call_site());
146 
147     let mut subcommands = Vec::new();
148     for (variant, item) in variants {
149         let kind = item.kind();
150 
151         let genned = match &*kind {
152             Kind::Skip(_, _) | Kind::Arg(_) | Kind::FromGlobal(_) | Kind::Value => None,
153 
154             Kind::ExternalSubcommand => {
155                 let ty = match variant.fields {
156                     Unnamed(ref fields) if fields.unnamed.len() == 1 => &fields.unnamed[0].ty,
157 
158                     _ => abort!(
159                         variant,
160                         "The enum variant marked with `external_subcommand` must be \
161                              a single-typed tuple, and the type must be either `Vec<String>` \
162                              or `Vec<OsString>`."
163                     ),
164                 };
165                 let deprecations = if !override_required {
166                     item.deprecations()
167                 } else {
168                     quote!()
169                 };
170                 let subty = subty_if_name(ty, "Vec").ok_or_else(|| {
171                     format_err!(
172                         ty.span(),
173                         "The type must be `Vec<_>` \
174                              to be used with `external_subcommand`."
175                     )
176                 })?;
177                 let subcommand = quote_spanned! { kind.span()=>
178                     #deprecations
179                     let #app_var = #app_var
180                         .external_subcommand_value_parser(clap::value_parser!(#subty));
181                 };
182                 Some(subcommand)
183             }
184 
185             Kind::Flatten(_) => match variant.fields {
186                 Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
187                     let ty = &unnamed[0].ty;
188                     let deprecations = if !override_required {
189                         item.deprecations()
190                     } else {
191                         quote!()
192                     };
193                     let next_help_heading = item.next_help_heading();
194                     let next_display_order = item.next_display_order();
195                     let subcommand = if override_required {
196                         quote! {
197                             #deprecations
198                             let #app_var = #app_var
199                                 #next_help_heading
200                                 #next_display_order;
201                             let #app_var = <#ty as clap::Subcommand>::augment_subcommands_for_update(#app_var);
202                         }
203                     } else {
204                         quote! {
205                             #deprecations
206                             let #app_var = #app_var
207                                 #next_help_heading
208                                 #next_display_order;
209                             let #app_var = <#ty as clap::Subcommand>::augment_subcommands(#app_var);
210                         }
211                     };
212                     Some(subcommand)
213                 }
214                 _ => abort!(
215                     variant,
216                     "`flatten` is usable only with single-typed tuple variants"
217                 ),
218             },
219 
220             Kind::Subcommand(_) => {
221                 let subcommand_var = Ident::new("__clap_subcommand", Span::call_site());
222                 let arg_block = match variant.fields {
223                     Named(_) => {
224                         abort!(variant, "non single-typed tuple enums are not supported")
225                     }
226                     Unit => quote!( #subcommand_var ),
227                     Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
228                         let ty = &unnamed[0].ty;
229                         if override_required {
230                             quote_spanned! { ty.span()=>
231                                 {
232                                     <#ty as clap::Subcommand>::augment_subcommands_for_update(#subcommand_var)
233                                 }
234                             }
235                         } else {
236                             quote_spanned! { ty.span()=>
237                                 {
238                                     <#ty as clap::Subcommand>::augment_subcommands(#subcommand_var)
239                                 }
240                             }
241                         }
242                     }
243                     Unnamed(..) => {
244                         abort!(variant, "non single-typed tuple enums are not supported")
245                     }
246                 };
247 
248                 let name = item.cased_name();
249                 let deprecations = if !override_required {
250                     item.deprecations()
251                 } else {
252                     quote!()
253                 };
254                 let initial_app_methods = item.initial_top_level_methods();
255                 let final_from_attrs = item.final_top_level_methods();
256                 let override_methods = if override_required {
257                     quote_spanned! { kind.span()=>
258                         .subcommand_required(false)
259                         .arg_required_else_help(false)
260                     }
261                 } else {
262                     quote!()
263                 };
264                 let subcommand = quote! {
265                     let #app_var = #app_var.subcommand({
266                         #deprecations;
267                         let #subcommand_var = clap::Command::new(#name);
268                         let #subcommand_var = #subcommand_var
269                             .subcommand_required(true)
270                             .arg_required_else_help(true);
271                         let #subcommand_var = #subcommand_var #initial_app_methods;
272                         let #subcommand_var = #arg_block;
273                         #subcommand_var #final_from_attrs #override_methods
274                     });
275                 };
276                 Some(subcommand)
277             }
278 
279             Kind::Command(_) => {
280                 let subcommand_var = Ident::new("__clap_subcommand", Span::call_site());
281                 let sub_augment = match variant.fields {
282                     Named(ref fields) => {
283                         // Defer to `gen_augment` for adding cmd methods
284                         let fields = collect_args_fields(item, fields)?;
285                         args::gen_augment(&fields, &subcommand_var, item, override_required)?
286                     }
287                     Unit => {
288                         let arg_block = quote!( #subcommand_var );
289                         let initial_app_methods = item.initial_top_level_methods();
290                         let final_from_attrs = item.final_top_level_methods();
291                         quote! {
292                             let #subcommand_var = #subcommand_var #initial_app_methods;
293                             let #subcommand_var = #arg_block;
294                             #subcommand_var #final_from_attrs
295                         }
296                     }
297                     Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
298                         let ty = &unnamed[0].ty;
299                         let arg_block = if override_required {
300                             quote_spanned! { ty.span()=>
301                                 {
302                                     <#ty as clap::Args>::augment_args_for_update(#subcommand_var)
303                                 }
304                             }
305                         } else {
306                             quote_spanned! { ty.span()=>
307                                 {
308                                     <#ty as clap::Args>::augment_args(#subcommand_var)
309                                 }
310                             }
311                         };
312                         let initial_app_methods = item.initial_top_level_methods();
313                         let final_from_attrs = item.final_top_level_methods();
314                         quote! {
315                             let #subcommand_var = #subcommand_var #initial_app_methods;
316                             let #subcommand_var = #arg_block;
317                             #subcommand_var #final_from_attrs
318                         }
319                     }
320                     Unnamed(..) => {
321                         abort!(variant, "non single-typed tuple enums are not supported")
322                     }
323                 };
324 
325                 let deprecations = if !override_required {
326                     item.deprecations()
327                 } else {
328                     quote!()
329                 };
330                 let name = item.cased_name();
331                 let subcommand = quote! {
332                     let #app_var = #app_var.subcommand({
333                         #deprecations
334                         let #subcommand_var = clap::Command::new(#name);
335                         #sub_augment
336                     });
337                 };
338                 Some(subcommand)
339             }
340         };
341         subcommands.push(genned);
342     }
343 
344     let deprecations = if !override_required {
345         parent_item.deprecations()
346     } else {
347         quote!()
348     };
349     let initial_app_methods = parent_item.initial_top_level_methods();
350     let final_app_methods = parent_item.final_top_level_methods();
351     Ok(quote! {
352         #deprecations;
353         let #app_var = #app_var #initial_app_methods;
354         #( #subcommands )*;
355         #app_var #final_app_methods
356     })
357 }
358 
gen_has_subcommand(variants: &[(&Variant, Item)]) -> Result<TokenStream, syn::Error>359 fn gen_has_subcommand(variants: &[(&Variant, Item)]) -> Result<TokenStream, syn::Error> {
360     use syn::Fields::*;
361 
362     let mut ext_subcmd = false;
363 
364     let (flatten_variants, variants): (Vec<_>, Vec<_>) = variants
365         .iter()
366         .filter_map(|(variant, item)| {
367             let kind = item.kind();
368             match &*kind {
369                 Kind::Skip(_, _) | Kind::Arg(_) | Kind::FromGlobal(_) | Kind::Value => None,
370 
371                 Kind::ExternalSubcommand => {
372                     ext_subcmd = true;
373                     None
374                 }
375                 Kind::Flatten(_) | Kind::Subcommand(_) | Kind::Command(_) => Some((variant, item)),
376             }
377         })
378         .partition(|(_, item)| {
379             let kind = item.kind();
380             matches!(&*kind, Kind::Flatten(_))
381         });
382 
383     let subcommands = variants.iter().map(|(_variant, item)| {
384         let sub_name = item.cased_name();
385         quote! {
386             if #sub_name == __clap_name {
387                 return true
388             }
389         }
390     });
391     let child_subcommands = flatten_variants
392         .iter()
393         .map(|(variant, _attrs)| match variant.fields {
394             Unnamed(ref fields) if fields.unnamed.len() == 1 => {
395                 let ty = &fields.unnamed[0].ty;
396                 Ok(quote! {
397                     if <#ty as clap::Subcommand>::has_subcommand(__clap_name) {
398                         return true;
399                     }
400                 })
401             }
402             _ => abort!(
403                 variant,
404                 "`flatten` is usable only with single-typed tuple variants"
405             ),
406         })
407         .collect::<Result<Vec<_>, syn::Error>>()?;
408 
409     let genned = if ext_subcmd {
410         quote! { true }
411     } else {
412         quote! {
413             #( #subcommands )*
414 
415             #( #child_subcommands )else*
416 
417             false
418         }
419     };
420     Ok(genned)
421 }
422 
gen_from_arg_matches(variants: &[(&Variant, Item)]) -> Result<TokenStream, syn::Error>423 fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> Result<TokenStream, syn::Error> {
424     use syn::Fields::*;
425 
426     let subcommand_name_var = format_ident!("__clap_name");
427     let sub_arg_matches_var = format_ident!("__clap_arg_matches");
428 
429     let mut ext_subcmd = None;
430     let mut flatten_variants = Vec::new();
431     let mut unflatten_variants = Vec::new();
432     for (variant, item) in variants {
433         let kind = item.kind();
434         match &*kind {
435             Kind::Skip(_, _) | Kind::Arg(_) | Kind::FromGlobal(_) | Kind::Value => {}
436 
437             Kind::ExternalSubcommand => {
438                 if ext_subcmd.is_some() {
439                     abort!(
440                         item.kind().span(),
441                         "Only one variant can be marked with `external_subcommand`, \
442                          this is the second"
443                     );
444                 }
445 
446                 let ty = match variant.fields {
447                     Unnamed(ref fields) if fields.unnamed.len() == 1 => &fields.unnamed[0].ty,
448 
449                     _ => abort!(
450                         variant,
451                         "The enum variant marked with `external_subcommand` must be \
452                          a single-typed tuple, and the type must be either `Vec<String>` \
453                          or `Vec<OsString>`."
454                     ),
455                 };
456 
457                 let (span, str_ty) = match subty_if_name(ty, "Vec") {
458                     Some(subty) => {
459                         if is_simple_ty(subty, "String") {
460                             (subty.span(), quote!(::std::string::String))
461                         } else if is_simple_ty(subty, "OsString") {
462                             (subty.span(), quote!(::std::ffi::OsString))
463                         } else {
464                             abort!(
465                                 ty.span(),
466                                 "The type must be either `Vec<String>` or `Vec<OsString>` \
467                                  to be used with `external_subcommand`."
468                             );
469                         }
470                     }
471 
472                     None => abort!(
473                         ty.span(),
474                         "The type must be either `Vec<String>` or `Vec<OsString>` \
475                          to be used with `external_subcommand`."
476                     ),
477                 };
478 
479                 ext_subcmd = Some((span, &variant.ident, str_ty));
480             }
481             Kind::Flatten(_) | Kind::Subcommand(_) | Kind::Command(_) => {
482                 if matches!(&*item.kind(), Kind::Flatten(_)) {
483                     flatten_variants.push((variant, item));
484                 } else {
485                     unflatten_variants.push((variant, item));
486                 }
487             }
488         }
489     }
490 
491     let subcommands = unflatten_variants.iter().map(|(variant, item)| {
492         let sub_name = item.cased_name();
493         let variant_name = &variant.ident;
494         let constructor_block = match variant.fields {
495             Named(ref fields) => {
496                 let fields = collect_args_fields(item, fields)?;
497                 args::gen_constructor(&fields)?
498             },
499             Unit => quote!(),
500             Unnamed(ref fields) if fields.unnamed.len() == 1 => {
501                 let ty = &fields.unnamed[0].ty;
502                 quote!( ( <#ty as clap::FromArgMatches>::from_arg_matches_mut(__clap_arg_matches)? ) )
503             }
504             Unnamed(..) => abort_call_site!("{}: tuple enums are not supported", variant.ident),
505         };
506 
507         Ok(quote! {
508             if #subcommand_name_var == #sub_name && !#sub_arg_matches_var.contains_id("") {
509                 return ::std::result::Result::Ok(Self :: #variant_name #constructor_block)
510             }
511         })
512     }).collect::<Result<Vec<_>, syn::Error>>()?;
513     let child_subcommands = flatten_variants.iter().map(|(variant, _attrs)| {
514         let variant_name = &variant.ident;
515         match variant.fields {
516             Unnamed(ref fields) if fields.unnamed.len() == 1 => {
517                 let ty = &fields.unnamed[0].ty;
518                 Ok(quote! {
519                     if __clap_arg_matches
520                         .subcommand_name()
521                         .map(|__clap_name| <#ty as clap::Subcommand>::has_subcommand(__clap_name))
522                         .unwrap_or_default()
523                     {
524                         let __clap_res = <#ty as clap::FromArgMatches>::from_arg_matches_mut(__clap_arg_matches)?;
525                         return ::std::result::Result::Ok(Self :: #variant_name (__clap_res));
526                     }
527                 })
528             }
529             _ => abort!(
530                 variant,
531                 "`flatten` is usable only with single-typed tuple variants"
532             ),
533         }
534     }).collect::<Result<Vec<_>, syn::Error>>()?;
535 
536     let wildcard = match ext_subcmd {
537         Some((span, var_name, str_ty)) => quote_spanned! { span=>
538                 ::std::result::Result::Ok(Self::#var_name(
539                     ::std::iter::once(#str_ty::from(#subcommand_name_var))
540                     .chain(
541                         #sub_arg_matches_var
542                             .remove_many::<#str_ty>("")
543                             .unwrap()
544                             .map(#str_ty::from)
545                     )
546                     .collect::<::std::vec::Vec<_>>()
547                 ))
548         },
549 
550         None => quote! {
551             ::std::result::Result::Err(clap::Error::raw(clap::error::ErrorKind::InvalidSubcommand, format!("The subcommand '{}' wasn't recognized", #subcommand_name_var)))
552         },
553     };
554 
555     let raw_deprecated = args::raw_deprecated();
556     Ok(quote! {
557         fn from_arg_matches_mut(__clap_arg_matches: &mut clap::ArgMatches) -> ::std::result::Result<Self, clap::Error> {
558             #raw_deprecated
559 
560             #( #child_subcommands )else*
561 
562             if let Some((#subcommand_name_var, mut __clap_arg_sub_matches)) = __clap_arg_matches.remove_subcommand() {
563                 let #sub_arg_matches_var = &mut __clap_arg_sub_matches;
564                 #( #subcommands )*
565 
566                 #wildcard
567             } else {
568                 ::std::result::Result::Err(clap::Error::raw(clap::error::ErrorKind::MissingSubcommand, "A subcommand is required but one was not provided."))
569             }
570         }
571     })
572 }
573 
gen_update_from_arg_matches(variants: &[(&Variant, Item)]) -> Result<TokenStream, syn::Error>574 fn gen_update_from_arg_matches(variants: &[(&Variant, Item)]) -> Result<TokenStream, syn::Error> {
575     use syn::Fields::*;
576 
577     let (flatten, variants): (Vec<_>, Vec<_>) = variants
578         .iter()
579         .filter_map(|(variant, item)| {
580             let kind = item.kind();
581             match &*kind {
582                 // Fallback to `from_arg_matches_mut`
583                 Kind::Skip(_, _)
584                 | Kind::Arg(_)
585                 | Kind::FromGlobal(_)
586                 | Kind::Value
587                 | Kind::ExternalSubcommand => None,
588                 Kind::Flatten(_) | Kind::Subcommand(_) | Kind::Command(_) => Some((variant, item)),
589             }
590         })
591         .partition(|(_, item)| {
592             let kind = item.kind();
593             matches!(&*kind, Kind::Flatten(_))
594         });
595 
596     let subcommands = variants.iter().map(|(variant, item)| {
597         let sub_name = item.cased_name();
598         let variant_name = &variant.ident;
599         let (pattern, updater) = match variant.fields {
600             Named(ref fields) => {
601                 let field_names = fields.named.iter().map(|field| {
602                     field.ident.as_ref().unwrap()
603                 }).collect::<Vec<_>>();
604                 let fields = collect_args_fields(item, fields)?;
605                 let update = args::gen_updater(&fields, false)?;
606                 (quote!( { #( #field_names, )* }), quote!( { #update } ))
607             }
608             Unit => (quote!(), quote!({})),
609             Unnamed(ref fields) => {
610                 if fields.unnamed.len() == 1 {
611                     (
612                         quote!((ref mut __clap_arg)),
613                         quote!(clap::FromArgMatches::update_from_arg_matches_mut(
614                             __clap_arg,
615                             __clap_arg_matches
616                         )?),
617                     )
618                 } else {
619                     abort_call_site!("{}: tuple enums are not supported", variant.ident)
620                 }
621             }
622         };
623 
624         Ok(quote! {
625             Self :: #variant_name #pattern if #sub_name == __clap_name => {
626                 let (_, mut __clap_arg_sub_matches) = __clap_arg_matches.remove_subcommand().unwrap();
627                 let __clap_arg_matches = &mut __clap_arg_sub_matches;
628                 #updater
629             }
630         })
631     }).collect::<Result<Vec<_>, _>>()?;
632 
633     let child_subcommands = flatten.iter().map(|(variant, _attrs)| {
634         let variant_name = &variant.ident;
635         match variant.fields {
636             Unnamed(ref fields) if fields.unnamed.len() == 1 => {
637                 let ty = &fields.unnamed[0].ty;
638                 Ok(quote! {
639                     if <#ty as clap::Subcommand>::has_subcommand(__clap_name) {
640                         if let Self :: #variant_name (child) = s {
641                             <#ty as clap::FromArgMatches>::update_from_arg_matches_mut(child, __clap_arg_matches)?;
642                             return ::std::result::Result::Ok(());
643                         }
644                     }
645                 })
646             }
647             _ => abort!(
648                 variant,
649                 "`flatten` is usable only with single-typed tuple variants"
650             ),
651         }
652     }).collect::<Result<Vec<_>, _>>()?;
653 
654     let raw_deprecated = args::raw_deprecated();
655     Ok(quote! {
656         fn update_from_arg_matches_mut<'b>(
657             &mut self,
658             __clap_arg_matches: &mut clap::ArgMatches,
659         ) -> ::std::result::Result<(), clap::Error> {
660             #raw_deprecated
661 
662             if let Some(__clap_name) = __clap_arg_matches.subcommand_name() {
663                 match self {
664                     #( #subcommands ),*
665                     s => {
666                         #( #child_subcommands )*
667                         *s = <Self as clap::FromArgMatches>::from_arg_matches_mut(__clap_arg_matches)?;
668                     }
669                 }
670             }
671             ::std::result::Result::Ok(())
672         }
673     })
674 }
675