aboutsummaryrefslogtreecommitdiff
path: root/vendor/clap_builder/src/output/usage.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/clap_builder/src/output/usage.rs')
-rw-r--r--vendor/clap_builder/src/output/usage.rs529
1 files changed, 0 insertions, 529 deletions
diff --git a/vendor/clap_builder/src/output/usage.rs b/vendor/clap_builder/src/output/usage.rs
deleted file mode 100644
index d75b704..0000000
--- a/vendor/clap_builder/src/output/usage.rs
+++ /dev/null
@@ -1,529 +0,0 @@
-#![cfg_attr(not(feature = "usage"), allow(unused_imports))]
-#![cfg_attr(not(feature = "usage"), allow(unused_variables))]
-#![cfg_attr(not(feature = "usage"), allow(clippy::manual_map))]
-#![cfg_attr(not(feature = "usage"), allow(dead_code))]
-
-// Internal
-use crate::builder::ArgAction;
-use crate::builder::StyledStr;
-use crate::builder::Styles;
-use crate::builder::{ArgPredicate, Command};
-use crate::parser::ArgMatcher;
-use crate::util::ChildGraph;
-use crate::util::FlatSet;
-use crate::util::Id;
-
-static DEFAULT_SUB_VALUE_NAME: &str = "COMMAND";
-const USAGE_SEP: &str = "\n ";
-
-pub(crate) struct Usage<'cmd> {
- cmd: &'cmd Command,
- styles: &'cmd Styles,
- required: Option<&'cmd ChildGraph<Id>>,
-}
-
-impl<'cmd> Usage<'cmd> {
- pub(crate) fn new(cmd: &'cmd Command) -> Self {
- Usage {
- cmd,
- styles: cmd.get_styles(),
- required: None,
- }
- }
-
- pub(crate) fn required(mut self, required: &'cmd ChildGraph<Id>) -> Self {
- self.required = Some(required);
- self
- }
-
- // Creates a usage string for display. This happens just after all arguments were parsed, but before
- // any subcommands have been parsed (so as to give subcommands their own usage recursively)
- pub(crate) fn create_usage_with_title(&self, used: &[Id]) -> Option<StyledStr> {
- debug!("Usage::create_usage_with_title");
- use std::fmt::Write as _;
- let mut styled = StyledStr::new();
- let _ = write!(
- styled,
- "{}Usage:{} ",
- self.styles.get_usage().render(),
- self.styles.get_usage().render_reset()
- );
- if self.write_usage_no_title(&mut styled, used) {
- styled.trim_end();
- } else {
- return None;
- }
- debug!("Usage::create_usage_with_title: usage={styled}");
- Some(styled)
- }
-
- // Creates a usage string (*without title*) if one was not provided by the user manually.
- pub(crate) fn create_usage_no_title(&self, used: &[Id]) -> Option<StyledStr> {
- debug!("Usage::create_usage_no_title");
-
- let mut styled = StyledStr::new();
- if self.write_usage_no_title(&mut styled, used) {
- styled.trim_end();
- debug!("Usage::create_usage_no_title: usage={styled}");
- Some(styled)
- } else {
- None
- }
- }
-
- // Creates a usage string (*without title*) if one was not provided by the user manually.
- fn write_usage_no_title(&self, styled: &mut StyledStr, used: &[Id]) -> bool {
- debug!("Usage::create_usage_no_title");
- if let Some(u) = self.cmd.get_override_usage() {
- styled.push_styled(u);
- true
- } else {
- #[cfg(feature = "usage")]
- {
- if used.is_empty() {
- self.write_help_usage(styled);
- } else {
- self.write_smart_usage(styled, used);
- }
- true
- }
-
- #[cfg(not(feature = "usage"))]
- {
- false
- }
- }
- }
-}
-
-#[cfg(feature = "usage")]
-impl<'cmd> Usage<'cmd> {
- // Creates a usage string for display in help messages (i.e. not for errors)
- fn write_help_usage(&self, styled: &mut StyledStr) {
- debug!("Usage::write_help_usage");
- use std::fmt::Write;
-
- if self.cmd.has_visible_subcommands() && self.cmd.is_flatten_help_set() {
- if !self.cmd.is_subcommand_required_set()
- || self.cmd.is_args_conflicts_with_subcommands_set()
- {
- self.write_arg_usage(styled, &[], true);
- styled.trim_end();
- let _ = write!(styled, "{}", USAGE_SEP);
- }
- let mut cmd = self.cmd.clone();
- cmd.build();
- for (i, sub) in cmd
- .get_subcommands()
- .filter(|c| !c.is_hide_set())
- .enumerate()
- {
- if i != 0 {
- styled.trim_end();
- let _ = write!(styled, "{}", USAGE_SEP);
- }
- Usage::new(sub).write_usage_no_title(styled, &[]);
- }
- } else {
- self.write_arg_usage(styled, &[], true);
- self.write_subcommand_usage(styled);
- }
- }
-
- // Creates a context aware usage string, or "smart usage" from currently used
- // args, and requirements
- fn write_smart_usage(&self, styled: &mut StyledStr, used: &[Id]) {
- debug!("Usage::create_smart_usage");
- use std::fmt::Write;
- let placeholder = &self.styles.get_placeholder();
-
- self.write_arg_usage(styled, used, true);
-
- if self.cmd.is_subcommand_required_set() {
- let value_name = self
- .cmd
- .get_subcommand_value_name()
- .unwrap_or(DEFAULT_SUB_VALUE_NAME);
- let _ = write!(
- styled,
- "{}<{value_name}>{}",
- placeholder.render(),
- placeholder.render_reset()
- );
- }
- }
-
- fn write_arg_usage(&self, styled: &mut StyledStr, used: &[Id], incl_reqs: bool) {
- debug!("Usage::write_arg_usage; incl_reqs={incl_reqs:?}");
- use std::fmt::Write as _;
- let literal = &self.styles.get_literal();
- let placeholder = &self.styles.get_placeholder();
-
- let bin_name = self.cmd.get_usage_name_fallback();
- if !bin_name.is_empty() {
- // the trim won't properly remove a leading space due to the formatting
- let _ = write!(
- styled,
- "{}{bin_name}{} ",
- literal.render(),
- literal.render_reset()
- );
- }
-
- if used.is_empty() && self.needs_options_tag() {
- let _ = write!(
- styled,
- "{}[OPTIONS]{} ",
- placeholder.render(),
- placeholder.render_reset()
- );
- }
-
- self.write_args(styled, used, !incl_reqs);
- }
-
- fn write_subcommand_usage(&self, styled: &mut StyledStr) {
- debug!("Usage::write_subcommand_usage");
- use std::fmt::Write as _;
-
- // incl_reqs is only false when this function is called recursively
- if self.cmd.has_visible_subcommands() || self.cmd.is_allow_external_subcommands_set() {
- let literal = &self.styles.get_literal();
- let placeholder = &self.styles.get_placeholder();
- let value_name = self
- .cmd
- .get_subcommand_value_name()
- .unwrap_or(DEFAULT_SUB_VALUE_NAME);
- if self.cmd.is_subcommand_negates_reqs_set()
- || self.cmd.is_args_conflicts_with_subcommands_set()
- {
- styled.trim_end();
- let _ = write!(styled, "{}", USAGE_SEP);
- if self.cmd.is_args_conflicts_with_subcommands_set() {
- let bin_name = self.cmd.get_usage_name_fallback();
- // Short-circuit full usage creation since no args will be relevant
- let _ = write!(
- styled,
- "{}{bin_name}{} ",
- literal.render(),
- literal.render_reset()
- );
- } else {
- self.write_arg_usage(styled, &[], false);
- }
- let _ = write!(
- styled,
- "{}<{value_name}>{}",
- placeholder.render(),
- placeholder.render_reset()
- );
- } else if self.cmd.is_subcommand_required_set() {
- let _ = write!(
- styled,
- "{}<{value_name}>{}",
- placeholder.render(),
- placeholder.render_reset()
- );
- } else {
- let _ = write!(
- styled,
- "{}[{value_name}]{}",
- placeholder.render(),
- placeholder.render_reset()
- );
- }
- }
- }
-
- // Determines if we need the `[OPTIONS]` tag in the usage string
- fn needs_options_tag(&self) -> bool {
- debug!("Usage::needs_options_tag");
- 'outer: for f in self.cmd.get_non_positionals() {
- debug!("Usage::needs_options_tag:iter: f={}", f.get_id());
-
- // Don't print `[OPTIONS]` just for help or version
- if f.get_long() == Some("help") || f.get_long() == Some("version") {
- debug!("Usage::needs_options_tag:iter Option is built-in");
- continue;
- }
- match f.get_action() {
- ArgAction::Set
- | ArgAction::Append
- | ArgAction::SetTrue
- | ArgAction::SetFalse
- | ArgAction::Count => {}
- ArgAction::Help
- | ArgAction::HelpShort
- | ArgAction::HelpLong
- | ArgAction::Version => {
- debug!("Usage::needs_options_tag:iter Option is built-in");
- continue;
- }
- }
-
- if f.is_hide_set() {
- debug!("Usage::needs_options_tag:iter Option is hidden");
- continue;
- }
- if f.is_required_set() {
- debug!("Usage::needs_options_tag:iter Option is required");
- continue;
- }
- for grp_s in self.cmd.groups_for_arg(f.get_id()) {
- debug!("Usage::needs_options_tag:iter:iter: grp_s={grp_s:?}");
- if self.cmd.get_groups().any(|g| g.id == grp_s && g.required) {
- debug!("Usage::needs_options_tag:iter:iter: Group is required");
- continue 'outer;
- }
- }
-
- debug!("Usage::needs_options_tag:iter: [OPTIONS] required");
- return true;
- }
-
- debug!("Usage::needs_options_tag: [OPTIONS] not required");
- false
- }
-
- // Returns the required args in usage string form by fully unrolling all groups
- pub(crate) fn write_args(&self, styled: &mut StyledStr, incls: &[Id], force_optional: bool) {
- debug!("Usage::write_args: incls={incls:?}",);
- use std::fmt::Write as _;
- let literal = &self.styles.get_literal();
-
- let required_owned;
- let required = if let Some(required) = self.required {
- required
- } else {
- required_owned = self.cmd.required_graph();
- &required_owned
- };
-
- let mut unrolled_reqs = Vec::new();
- for a in required.iter() {
- let is_relevant = |(val, req_arg): &(ArgPredicate, Id)| -> Option<Id> {
- let required = match val {
- ArgPredicate::Equals(_) => false,
- ArgPredicate::IsPresent => true,
- };
- required.then(|| req_arg.clone())
- };
-
- for aa in self.cmd.unroll_arg_requires(is_relevant, a) {
- // if we don't check for duplicates here this causes duplicate error messages
- // see https://github.com/clap-rs/clap/issues/2770
- unrolled_reqs.push(aa);
- }
- // always include the required arg itself. it will not be enumerated
- // by unroll_requirements_for_arg.
- unrolled_reqs.push(a.clone());
- }
- debug!("Usage::get_args: unrolled_reqs={unrolled_reqs:?}");
-
- let mut required_groups_members = FlatSet::new();
- let mut required_groups = FlatSet::new();
- for req in unrolled_reqs.iter().chain(incls.iter()) {
- if self.cmd.find_group(req).is_some() {
- let group_members = self.cmd.unroll_args_in_group(req);
- let elem = self.cmd.format_group(req);
- required_groups.insert(elem);
- required_groups_members.extend(group_members);
- } else {
- debug_assert!(self.cmd.find(req).is_some());
- }
- }
-
- let mut required_opts = FlatSet::new();
- let mut required_positionals = Vec::new();
- for req in unrolled_reqs.iter().chain(incls.iter()) {
- if let Some(arg) = self.cmd.find(req) {
- if required_groups_members.contains(arg.get_id()) {
- continue;
- }
-
- let stylized = arg.stylized(self.styles, Some(!force_optional));
- if let Some(index) = arg.get_index() {
- let new_len = index + 1;
- if required_positionals.len() < new_len {
- required_positionals.resize(new_len, None);
- }
- required_positionals[index] = Some(stylized);
- } else {
- required_opts.insert(stylized);
- }
- } else {
- debug_assert!(self.cmd.find_group(req).is_some());
- }
- }
-
- for pos in self.cmd.get_positionals() {
- if pos.is_hide_set() {
- continue;
- }
- if required_groups_members.contains(pos.get_id()) {
- continue;
- }
-
- let index = pos.get_index().unwrap();
- let new_len = index + 1;
- if required_positionals.len() < new_len {
- required_positionals.resize(new_len, None);
- }
- if required_positionals[index].is_some() {
- if pos.is_last_set() {
- let styled = required_positionals[index].take().unwrap();
- let mut new = StyledStr::new();
- let _ = write!(new, "{}--{} ", literal.render(), literal.render_reset());
- new.push_styled(&styled);
- required_positionals[index] = Some(new);
- }
- } else {
- let mut styled;
- if pos.is_last_set() {
- styled = StyledStr::new();
- let _ = write!(styled, "{}[--{} ", literal.render(), literal.render_reset());
- styled.push_styled(&pos.stylized(self.styles, Some(true)));
- let _ = write!(styled, "{}]{}", literal.render(), literal.render_reset());
- } else {
- styled = pos.stylized(self.styles, Some(false));
- }
- required_positionals[index] = Some(styled);
- }
- if pos.is_last_set() && force_optional {
- required_positionals[index] = None;
- }
- }
-
- if !force_optional {
- for arg in required_opts {
- styled.push_styled(&arg);
- styled.push_str(" ");
- }
- for arg in required_groups {
- styled.push_styled(&arg);
- styled.push_str(" ");
- }
- }
- for arg in required_positionals.into_iter().flatten() {
- styled.push_styled(&arg);
- styled.push_str(" ");
- }
- }
-
- pub(crate) fn get_required_usage_from(
- &self,
- incls: &[Id],
- matcher: Option<&ArgMatcher>,
- incl_last: bool,
- ) -> Vec<StyledStr> {
- debug!(
- "Usage::get_required_usage_from: incls={:?}, matcher={:?}, incl_last={:?}",
- incls,
- matcher.is_some(),
- incl_last
- );
-
- let required_owned;
- let required = if let Some(required) = self.required {
- required
- } else {
- required_owned = self.cmd.required_graph();
- &required_owned
- };
-
- let mut unrolled_reqs = Vec::new();
- for a in required.iter() {
- let is_relevant = |(val, req_arg): &(ArgPredicate, Id)| -> Option<Id> {
- let required = match val {
- ArgPredicate::Equals(_) => {
- if let Some(matcher) = matcher {
- matcher.check_explicit(a, val)
- } else {
- false
- }
- }
- ArgPredicate::IsPresent => true,
- };
- required.then(|| req_arg.clone())
- };
-
- for aa in self.cmd.unroll_arg_requires(is_relevant, a) {
- // if we don't check for duplicates here this causes duplicate error messages
- // see https://github.com/clap-rs/clap/issues/2770
- unrolled_reqs.push(aa);
- }
- // always include the required arg itself. it will not be enumerated
- // by unroll_requirements_for_arg.
- unrolled_reqs.push(a.clone());
- }
- debug!("Usage::get_required_usage_from: unrolled_reqs={unrolled_reqs:?}");
-
- let mut required_groups_members = FlatSet::new();
- let mut required_groups = FlatSet::new();
- for req in unrolled_reqs.iter().chain(incls.iter()) {
- if self.cmd.find_group(req).is_some() {
- let group_members = self.cmd.unroll_args_in_group(req);
- let is_present = matcher
- .map(|m| {
- group_members
- .iter()
- .any(|arg| m.check_explicit(arg, &ArgPredicate::IsPresent))
- })
- .unwrap_or(false);
- debug!("Usage::get_required_usage_from:iter:{req:?} group is_present={is_present}");
- if is_present {
- continue;
- }
-
- let elem = self.cmd.format_group(req);
- required_groups.insert(elem);
- required_groups_members.extend(group_members);
- } else {
- debug_assert!(self.cmd.find(req).is_some(), "`{req}` must exist");
- }
- }
-
- let mut required_opts = FlatSet::new();
- let mut required_positionals = Vec::new();
- for req in unrolled_reqs.iter().chain(incls.iter()) {
- if let Some(arg) = self.cmd.find(req) {
- if required_groups_members.contains(arg.get_id()) {
- continue;
- }
-
- let is_present = matcher
- .map(|m| m.check_explicit(req, &ArgPredicate::IsPresent))
- .unwrap_or(false);
- debug!("Usage::get_required_usage_from:iter:{req:?} arg is_present={is_present}");
- if is_present {
- continue;
- }
-
- let stylized = arg.stylized(self.styles, Some(true));
- if let Some(index) = arg.get_index() {
- if !arg.is_last_set() || incl_last {
- let new_len = index + 1;
- if required_positionals.len() < new_len {
- required_positionals.resize(new_len, None);
- }
- required_positionals[index] = Some(stylized);
- }
- } else {
- required_opts.insert(stylized);
- }
- } else {
- debug_assert!(self.cmd.find_group(req).is_some());
- }
- }
-
- let mut ret_val = Vec::new();
- ret_val.extend(required_opts);
- ret_val.extend(required_groups);
- for pos in required_positionals.into_iter().flatten() {
- ret_val.push(pos);
- }
-
- debug!("Usage::get_required_usage_from: ret_val={ret_val:?}");
- ret_val
- }
-}