From 1b6a04ca5504955c571d1c97504fb45ea0befee4 Mon Sep 17 00:00:00 2001
From: Valentin Popov <valentin@popov.link>
Date: Mon, 8 Jan 2024 01:21:28 +0400
Subject: Initial vendor packages

Signed-off-by: Valentin Popov <valentin@popov.link>
---
 vendor/clap_builder/src/output/usage.rs | 529 ++++++++++++++++++++++++++++++++
 1 file changed, 529 insertions(+)
 create mode 100644 vendor/clap_builder/src/output/usage.rs

(limited to 'vendor/clap_builder/src/output/usage.rs')

diff --git a/vendor/clap_builder/src/output/usage.rs b/vendor/clap_builder/src/output/usage.rs
new file mode 100644
index 0000000..d75b704
--- /dev/null
+++ b/vendor/clap_builder/src/output/usage.rs
@@ -0,0 +1,529 @@
+#![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
+    }
+}
-- 
cgit v1.2.3