From 235cbb615e9f53bf960e33ee1e335e910b6927e4 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 14 Feb 2022 12:48:15 -0600 Subject: [PATCH] refactor: Centralize build logic --- src/build/app.rs | 53 +++++++++++++++++++++++++++++++++++++++++++++ src/parse/parser.rs | 50 +----------------------------------------- 2 files changed, 54 insertions(+), 49 deletions(-) diff --git a/src/build/app.rs b/src/build/app.rs index cfadfda3..e873f09b 100644 --- a/src/build/app.rs +++ b/src/build/app.rs @@ -3918,6 +3918,59 @@ impl<'help> App<'help> { self._build_bin_names(); } + pub(crate) fn _build_subcommand(&mut self, name: &str) -> Option<&mut Self> { + use std::fmt::Write; + + let mut mid_string = String::from(" "); + if !self.is_subcommand_negates_reqs_set() { + let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m) + + for s in &reqs { + mid_string.push_str(s); + mid_string.push(' '); + } + } + + let sc = self.subcommands.iter_mut().find(|s| s.name == name)?; + + // Display subcommand name, short and long in usage + let mut sc_names = sc.name.clone(); + let mut flag_subcmd = false; + if let Some(l) = sc.long_flag { + write!(sc_names, ", --{}", l).unwrap(); + flag_subcmd = true; + } + if let Some(s) = sc.short_flag { + write!(sc_names, ", -{}", s).unwrap(); + flag_subcmd = true; + } + + if flag_subcmd { + sc_names = format!("{{{}}}", sc_names); + } + + sc.usage = Some( + self.bin_name + .as_ref() + .map(|bin_name| format!("{}{}{}", bin_name, mid_string, sc_names)) + .unwrap_or(sc_names), + ); + + // bin_name should be parent's bin_name + [] + the sc's name separated by + // a space + sc.bin_name = Some(format!( + "{}{}{}", + self.bin_name.as_ref().unwrap_or(&String::new()), + if self.bin_name.is_some() { " " } else { "" }, + &*sc.name + )); + + // Ensure all args are built and ready to parse + sc._build(); + + Some(sc) + } + // used in clap_complete (https://github.com/clap-rs/clap_complete) #[doc(hidden)] pub fn _build(&mut self) { diff --git a/src/parse/parser.rs b/src/parse/parser.rs index d3eb495b..00a28567 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -2,7 +2,6 @@ use std::{ cell::{Cell, RefCell}, ffi::{OsStr, OsString}, - fmt::Write as _, }; // Third Party @@ -672,56 +671,9 @@ impl<'help, 'app> Parser<'help, 'app> { ) -> ClapResult<()> { debug!("Parser::parse_subcommand"); - let mut mid_string = String::from(" "); - - if !self.app.is_subcommand_negates_reqs_set() { - let reqs = Usage::new(self.app).get_required_usage_from(&[], None, true); // maybe Some(m) - - for s in &reqs { - mid_string.push_str(s); - mid_string.push(' '); - } - } - let partial_parsing_enabled = self.app.is_ignore_errors_set(); - if let Some(sc) = self.app.subcommands.iter_mut().find(|s| s.name == sc_name) { - // Display subcommand name, short and long in usage - let mut sc_names = sc.name.clone(); - let mut flag_subcmd = false; - if let Some(l) = sc.long_flag { - write!(sc_names, ", --{}", l).unwrap(); - flag_subcmd = true; - } - if let Some(s) = sc.short_flag { - write!(sc_names, ", -{}", s).unwrap(); - flag_subcmd = true; - } - - if flag_subcmd { - sc_names = format!("{{{}}}", sc_names); - } - - sc.usage = Some( - self.app - .bin_name - .as_ref() - .map(|bin_name| format!("{}{}{}", bin_name, mid_string, sc_names)) - .unwrap_or(sc_names), - ); - - // bin_name should be parent's bin_name + [] + the sc's name separated by - // a space - sc.bin_name = Some(format!( - "{}{}{}", - self.app.bin_name.as_ref().unwrap_or(&String::new()), - if self.app.bin_name.is_some() { " " } else { "" }, - &*sc.name - )); - - // Ensure all args are built and ready to parse - sc._build(); - + if let Some(sc) = self.app._build_subcommand(sc_name) { let mut sc_matcher = ArgMatcher::new(sc); debug!("Parser::parse_subcommand: About to parse sc={}", sc.name);