summaryrefslogtreecommitdiffstats
path: root/vendor/clap_builder/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/clap_builder/src')
-rw-r--r--vendor/clap_builder/src/builder/action.rs7
-rw-r--r--vendor/clap_builder/src/builder/arg.rs64
-rw-r--r--vendor/clap_builder/src/builder/command.rs71
-rw-r--r--vendor/clap_builder/src/builder/ext.rs216
-rw-r--r--vendor/clap_builder/src/builder/mod.rs6
-rw-r--r--vendor/clap_builder/src/builder/styled_str.rs231
-rw-r--r--vendor/clap_builder/src/builder/value_parser.rs4
-rw-r--r--vendor/clap_builder/src/error/format.rs375
-rw-r--r--vendor/clap_builder/src/error/mod.rs90
-rw-r--r--vendor/clap_builder/src/lib.rs4
-rw-r--r--vendor/clap_builder/src/macros.rs9
-rw-r--r--vendor/clap_builder/src/output/help.rs2
-rw-r--r--vendor/clap_builder/src/output/help_template.rs237
-rw-r--r--vendor/clap_builder/src/output/usage.rs123
-rw-r--r--vendor/clap_builder/src/parser/arg_matcher.rs6
-rw-r--r--vendor/clap_builder/src/parser/error.rs6
-rw-r--r--vendor/clap_builder/src/parser/matches/arg_matches.rs4
-rw-r--r--vendor/clap_builder/src/parser/matches/matched_arg.rs4
-rw-r--r--vendor/clap_builder/src/parser/matches/mod.rs3
-rw-r--r--vendor/clap_builder/src/parser/mod.rs2
-rw-r--r--vendor/clap_builder/src/parser/parser.rs27
-rw-r--r--vendor/clap_builder/src/parser/validator.rs10
-rw-r--r--vendor/clap_builder/src/util/any_value.rs (renamed from vendor/clap_builder/src/parser/matches/any_value.rs)0
-rw-r--r--vendor/clap_builder/src/util/mod.rs3
24 files changed, 1074 insertions, 430 deletions
diff --git a/vendor/clap_builder/src/builder/action.rs b/vendor/clap_builder/src/builder/action.rs
index becdeda0e..79ee9238e 100644
--- a/vendor/clap_builder/src/builder/action.rs
+++ b/vendor/clap_builder/src/builder/action.rs
@@ -1,3 +1,6 @@
+#[cfg(debug_assertions)]
+use crate::util::AnyValueId;
+
/// Behavior of arguments when they are encountered while parsing
///
/// # Examples
@@ -337,9 +340,7 @@ impl ArgAction {
}
#[cfg(debug_assertions)]
- pub(crate) fn value_type_id(&self) -> Option<crate::parser::AnyValueId> {
- use crate::parser::AnyValueId;
-
+ pub(crate) fn value_type_id(&self) -> Option<AnyValueId> {
match self {
Self::Set => None,
Self::Append => None,
diff --git a/vendor/clap_builder/src/builder/arg.rs b/vendor/clap_builder/src/builder/arg.rs
index 574e6fbaf..ce7e02d87 100644
--- a/vendor/clap_builder/src/builder/arg.rs
+++ b/vendor/clap_builder/src/builder/arg.rs
@@ -17,7 +17,9 @@ use crate::builder::OsStr;
use crate::builder::PossibleValue;
use crate::builder::Str;
use crate::builder::StyledStr;
+use crate::builder::Styles;
use crate::builder::ValueRange;
+use crate::util::AnyValueId;
use crate::ArgAction;
use crate::Id;
use crate::ValueHint;
@@ -4004,7 +4006,7 @@ impl Arg {
self.value_hint.unwrap_or_else(|| {
if self.is_takes_value_set() {
let type_id = self.get_value_parser().type_id();
- if type_id == crate::parser::AnyValueId::of::<std::path::PathBuf>() {
+ if type_id == AnyValueId::of::<std::path::PathBuf>() {
ValueHint::AnyPath
} else {
ValueHint::default()
@@ -4270,49 +4272,74 @@ impl Arg {
}
}
- pub(crate) fn stylized(&self, required: Option<bool>) -> StyledStr {
+ pub(crate) fn stylized(&self, styles: &Styles, required: Option<bool>) -> StyledStr {
+ use std::fmt::Write as _;
+ let literal = styles.get_literal();
+
let mut styled = StyledStr::new();
// Write the name such --long or -l
if let Some(l) = self.get_long() {
- styled.literal("--");
- styled.literal(l);
+ let _ = write!(
+ styled,
+ "{}--{l}{}",
+ literal.render(),
+ literal.render_reset()
+ );
} else if let Some(s) = self.get_short() {
- styled.literal("-");
- styled.literal(s);
+ let _ = write!(styled, "{}-{s}{}", literal.render(), literal.render_reset());
}
- styled.push_styled(&self.stylize_arg_suffix(required));
+ styled.push_styled(&self.stylize_arg_suffix(styles, required));
styled
}
- pub(crate) fn stylize_arg_suffix(&self, required: Option<bool>) -> StyledStr {
+ pub(crate) fn stylize_arg_suffix(&self, styles: &Styles, required: Option<bool>) -> StyledStr {
+ use std::fmt::Write as _;
+ let literal = styles.get_literal();
+ let placeholder = styles.get_placeholder();
let mut styled = StyledStr::new();
let mut need_closing_bracket = false;
if self.is_takes_value_set() && !self.is_positional() {
let is_optional_val = self.get_min_vals() == 0;
- if self.is_require_equals_set() {
+ let (style, start) = if self.is_require_equals_set() {
if is_optional_val {
need_closing_bracket = true;
- styled.placeholder("[=");
+ (placeholder, "[=")
} else {
- styled.literal("=");
+ (literal, "=")
}
} else if is_optional_val {
need_closing_bracket = true;
- styled.placeholder(" [");
+ (placeholder, " [")
} else {
- styled.placeholder(" ");
- }
+ (placeholder, " ")
+ };
+ let _ = write!(styled, "{}{start}{}", style.render(), style.render_reset());
}
if self.is_takes_value_set() || self.is_positional() {
let required = required.unwrap_or_else(|| self.is_required_set());
let arg_val = self.render_arg_val(required);
- styled.placeholder(arg_val);
+ let _ = write!(
+ styled,
+ "{}{arg_val}{}",
+ placeholder.render(),
+ placeholder.render_reset()
+ );
} else if matches!(*self.get_action(), ArgAction::Count) {
- styled.placeholder("...");
+ let _ = write!(
+ styled,
+ "{}...{}",
+ placeholder.render(),
+ placeholder.render_reset()
+ );
}
if need_closing_bracket {
- styled.placeholder("]");
+ let _ = write!(
+ styled,
+ "{}]{}",
+ placeholder.render(),
+ placeholder.render_reset()
+ );
}
styled
@@ -4400,7 +4427,8 @@ impl Eq for Arg {}
impl Display for Arg {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- self.stylized(None).fmt(f)
+ let plain = Styles::plain();
+ self.stylized(&plain, None).fmt(f)
}
}
diff --git a/vendor/clap_builder/src/builder/command.rs b/vendor/clap_builder/src/builder/command.rs
index 34c04b425..799623581 100644
--- a/vendor/clap_builder/src/builder/command.rs
+++ b/vendor/clap_builder/src/builder/command.rs
@@ -11,11 +11,13 @@ use std::path::Path;
// Internal
use crate::builder::app_settings::{AppFlags, AppSettings};
use crate::builder::arg_settings::ArgSettings;
+use crate::builder::ext::Extensions;
use crate::builder::ArgAction;
use crate::builder::IntoResettable;
use crate::builder::PossibleValue;
use crate::builder::Str;
use crate::builder::StyledStr;
+use crate::builder::Styles;
use crate::builder::{Arg, ArgGroup, ArgPredicate};
use crate::error::ErrorKind;
use crate::error::Result as ClapResult;
@@ -90,8 +92,6 @@ pub struct Command {
usage_name: Option<String>,
help_str: Option<StyledStr>,
disp_ord: Option<usize>,
- term_w: Option<usize>,
- max_w: Option<usize>,
#[cfg(feature = "help")]
template: Option<StyledStr>,
settings: AppFlags,
@@ -105,6 +105,7 @@ pub struct Command {
subcommand_heading: Option<Str>,
external_value_parser: Option<super::ValueParser>,
long_help_exists: bool,
+ app_ext: Extensions,
}
/// # Basic API
@@ -1080,6 +1081,30 @@ impl Command {
}
}
+ /// Sets the [`Styles`] for terminal output
+ ///
+ /// **NOTE:** This choice is propagated to all child subcommands.
+ ///
+ /// **NOTE:** Default behaviour is [`Styles::default`].
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # use clap_builder as clap;
+ /// # use clap::{Command, ColorChoice, builder::Styles};
+ /// Command::new("myprog")
+ /// .styles(Styles::styled().usage(Default::default()))
+ /// .get_matches();
+ /// ```
+ #[cfg(feature = "color")]
+ #[inline]
+ #[must_use]
+ #[cfg(feature = "unstable-styles")]
+ pub fn styles(mut self, styles: Styles) -> Self {
+ self.app_ext.set(styles);
+ self
+ }
+
/// Sets the terminal width at which to wrap help messages.
///
/// Using `0` will ignore terminal widths and use source formatting.
@@ -1104,7 +1129,7 @@ impl Command {
#[must_use]
#[cfg(any(not(feature = "unstable-v5"), feature = "wrap_help"))]
pub fn term_width(mut self, width: usize) -> Self {
- self.term_w = Some(width);
+ self.app_ext.set(TermWidth(width));
self
}
@@ -1131,8 +1156,8 @@ impl Command {
#[inline]
#[must_use]
#[cfg(any(not(feature = "unstable-v5"), feature = "wrap_help"))]
- pub fn max_term_width(mut self, w: usize) -> Self {
- self.max_w = Some(w);
+ pub fn max_term_width(mut self, width: usize) -> Self {
+ self.app_ext.set(MaxTermWidth(width));
self
}
@@ -1912,7 +1937,7 @@ impl Command {
self
}
- /// Change the starting value for assigning future display orders for ags.
+ /// Change the starting value for assigning future display orders for args.
///
/// This will be used for any arg that hasn't had [`Arg::display_order`] called.
#[inline]
@@ -3338,6 +3363,12 @@ impl Command {
}
}
+ /// Return the current `Styles` for the `Command`
+ #[inline]
+ pub fn get_styles(&self) -> &Styles {
+ self.app_ext.get().unwrap_or_default()
+ }
+
/// Iterate through the set of subcommands, getting a reference to each.
#[inline]
pub fn get_subcommands(&self) -> impl Iterator<Item = &Command> {
@@ -3720,12 +3751,12 @@ impl Command {
#[cfg(feature = "help")]
pub(crate) fn get_term_width(&self) -> Option<usize> {
- self.term_w
+ self.app_ext.get::<TermWidth>().map(|e| e.0)
}
#[cfg(feature = "help")]
pub(crate) fn get_max_term_width(&self) -> Option<usize> {
- self.max_w
+ self.app_ext.get::<MaxTermWidth>().map(|e| e.0)
}
pub(crate) fn get_keymap(&self) -> &MKeyMap {
@@ -4190,8 +4221,7 @@ impl Command {
sc.settings = sc.settings | self.g_settings;
sc.g_settings = sc.g_settings | self.g_settings;
- sc.term_w = self.term_w;
- sc.max_w = self.max_w;
+ sc.app_ext.update(&self.app_ext);
}
}
@@ -4322,9 +4352,9 @@ impl Command {
.collect::<Vec<_>>()
.join("|");
let mut styled = StyledStr::new();
- styled.none("<");
- styled.none(g_string);
- styled.none(">");
+ styled.push_str("<");
+ styled.push_string(g_string);
+ styled.push_str(">");
styled
}
}
@@ -4612,8 +4642,6 @@ impl Default for Command {
usage_name: Default::default(),
help_str: Default::default(),
disp_ord: Default::default(),
- term_w: Default::default(),
- max_w: Default::default(),
#[cfg(feature = "help")]
template: Default::default(),
settings: Default::default(),
@@ -4627,6 +4655,7 @@ impl Default for Command {
subcommand_heading: Default::default(),
external_value_parser: Default::default(),
long_help_exists: false,
+ app_ext: Default::default(),
}
}
}
@@ -4651,6 +4680,18 @@ impl fmt::Display for Command {
}
}
+pub(crate) trait AppTag: crate::builder::ext::Extension {}
+
+#[derive(Default, Copy, Clone, Debug)]
+struct TermWidth(usize);
+
+impl AppTag for TermWidth {}
+
+#[derive(Default, Copy, Clone, Debug)]
+struct MaxTermWidth(usize);
+
+impl AppTag for MaxTermWidth {}
+
fn two_elements_of<I, T>(mut iter: I) -> Option<(T, T)>
where
I: Iterator<Item = T>,
diff --git a/vendor/clap_builder/src/builder/ext.rs b/vendor/clap_builder/src/builder/ext.rs
new file mode 100644
index 000000000..2fb0d96b9
--- /dev/null
+++ b/vendor/clap_builder/src/builder/ext.rs
@@ -0,0 +1,216 @@
+use crate::util::AnyValueId;
+use crate::util::FlatMap;
+
+#[derive(Default, Clone, Debug)]
+pub(crate) struct Extensions {
+ extensions: FlatMap<AnyValueId, BoxedExtension>,
+}
+
+impl Extensions {
+ #[allow(dead_code)]
+ pub(crate) fn get<T: Extension>(&self) -> Option<&T> {
+ let id = AnyValueId::of::<T>();
+ self.extensions.get(&id).map(|e| e.as_ref::<T>())
+ }
+
+ #[allow(dead_code)]
+ pub(crate) fn get_mut<T: Extension>(&mut self) -> Option<&mut T> {
+ let id = AnyValueId::of::<T>();
+ self.extensions.get_mut(&id).map(|e| e.as_mut::<T>())
+ }
+
+ #[allow(dead_code)]
+ pub(crate) fn get_or_insert_default<T: Extension + Default>(&mut self) -> &mut T {
+ let id = AnyValueId::of::<T>();
+ self.extensions
+ .entry(id)
+ .or_insert_with(|| BoxedExtension::new(T::default()))
+ .as_mut::<T>()
+ }
+
+ #[allow(dead_code)]
+ pub(crate) fn set<T: Extension + Into<BoxedEntry>>(&mut self, tagged: T) -> bool {
+ let BoxedEntry { id, value } = tagged.into();
+ self.extensions.insert(id, value).is_some()
+ }
+
+ #[allow(dead_code)]
+ pub(crate) fn remove<T: Extension>(&mut self) -> Option<Box<dyn Extension>> {
+ let id = AnyValueId::of::<T>();
+ self.extensions.remove(&id).map(BoxedExtension::into_inner)
+ }
+
+ pub(crate) fn update(&mut self, other: &Self) {
+ for (key, value) in other.extensions.iter() {
+ self.extensions.insert(*key, value.clone());
+ }
+ }
+}
+
+/// Supports conversion to `Any`. Traits to be extended by `impl_downcast!` must extend `Extension`.
+pub(crate) trait Extension: std::fmt::Debug + Send + Sync + 'static {
+ /// Convert `Box<dyn Trait>` (where `Trait: Extension`) to `Box<dyn Any>`.
+ ///
+ /// `Box<dyn Any>` can /// then be further `downcast` into
+ /// `Box<ConcreteType>` where `ConcreteType` implements `Trait`.
+ fn into_any(self: Box<Self>) -> Box<dyn std::any::Any>;
+ /// Clone `&Box<dyn Trait>` (where `Trait: Extension`) to `Box<dyn Extension>`.
+ ///
+ /// `Box<dyn Any>` can /// then be further `downcast` into
+ // `Box<ConcreteType>` where `ConcreteType` implements `Trait`.
+ fn clone_extension(&self) -> Box<dyn Extension>;
+ /// Convert `&Trait` (where `Trait: Extension`) to `&Any`.
+ ///
+ /// This is needed since Rust cannot /// generate `&Any`'s vtable from
+ /// `&Trait`'s.
+ fn as_any(&self) -> &dyn std::any::Any;
+ /// Convert `&mut Trait` (where `Trait: Extension`) to `&Any`.
+ ///
+ /// This is needed since Rust cannot /// generate `&mut Any`'s vtable from
+ /// `&mut Trait`'s.
+ fn as_any_mut(&mut self) -> &mut dyn std::any::Any;
+}
+
+impl<T> Extension for T
+where
+ T: Clone + std::fmt::Debug + Send + Sync + 'static,
+{
+ fn into_any(self: Box<Self>) -> Box<dyn std::any::Any> {
+ self
+ }
+ fn clone_extension(&self) -> Box<dyn Extension> {
+ Box::new(self.clone())
+ }
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+ fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
+ self
+ }
+}
+
+impl Clone for Box<dyn Extension> {
+ fn clone(&self) -> Self {
+ self.as_ref().clone_extension()
+ }
+}
+
+#[derive(Clone)]
+#[repr(transparent)]
+struct BoxedExtension(Box<dyn Extension>);
+
+impl BoxedExtension {
+ fn new<T: Extension>(inner: T) -> Self {
+ Self(Box::new(inner))
+ }
+
+ fn into_inner(self) -> Box<dyn Extension> {
+ self.0
+ }
+
+ fn as_ref<T: Extension>(&self) -> &T {
+ self.0.as_ref().as_any().downcast_ref::<T>().unwrap()
+ }
+
+ fn as_mut<T: Extension>(&mut self) -> &mut T {
+ self.0.as_mut().as_any_mut().downcast_mut::<T>().unwrap()
+ }
+}
+
+impl std::fmt::Debug for BoxedExtension {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
+ self.0.fmt(f)
+ }
+}
+
+#[derive(Clone)]
+pub(crate) struct BoxedEntry {
+ id: AnyValueId,
+ value: BoxedExtension,
+}
+
+impl BoxedEntry {
+ pub(crate) fn new(r: impl Extension) -> Self {
+ let id = AnyValueId::from(&r);
+ let value = BoxedExtension::new(r);
+ BoxedEntry { id, value }
+ }
+}
+
+impl<R: Extension> From<R> for BoxedEntry {
+ fn from(inner: R) -> Self {
+ BoxedEntry::new(inner)
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
+ struct Number(usize);
+
+ #[test]
+ fn get() {
+ let mut ext = Extensions::default();
+ ext.set(Number(10));
+ assert_eq!(ext.get::<Number>(), Some(&Number(10)));
+ }
+
+ #[test]
+ fn get_mut() {
+ let mut ext = Extensions::default();
+ ext.set(Number(10));
+ *ext.get_mut::<Number>().unwrap() = Number(20);
+ assert_eq!(ext.get::<Number>(), Some(&Number(20)));
+ }
+
+ #[test]
+ fn get_or_insert_default_empty() {
+ let mut ext = Extensions::default();
+ assert_eq!(ext.get_or_insert_default::<Number>(), &Number(0));
+ }
+
+ #[test]
+ fn get_or_insert_default_full() {
+ let mut ext = Extensions::default();
+ ext.set(Number(10));
+ assert_eq!(ext.get_or_insert_default::<Number>(), &Number(10));
+ }
+
+ #[test]
+ fn set() {
+ let mut ext = Extensions::default();
+ assert!(!ext.set(Number(10)));
+ assert_eq!(ext.get::<Number>(), Some(&Number(10)));
+ assert!(ext.set(Number(20)));
+ assert_eq!(ext.get::<Number>(), Some(&Number(20)));
+ }
+
+ #[test]
+ fn reset() {
+ let mut ext = Extensions::default();
+ assert_eq!(ext.get::<Number>(), None);
+
+ assert!(ext.remove::<Number>().is_none());
+ assert_eq!(ext.get::<Number>(), None);
+
+ assert!(!ext.set(Number(10)));
+ assert_eq!(ext.get::<Number>(), Some(&Number(10)));
+
+ assert!(ext.remove::<Number>().is_some());
+ assert_eq!(ext.get::<Number>(), None);
+ }
+
+ #[test]
+ fn update() {
+ let mut ext = Extensions::default();
+ assert_eq!(ext.get::<Number>(), None);
+
+ let mut new = Extensions::default();
+ assert!(!new.set(Number(10)));
+
+ ext.update(&new);
+ assert_eq!(ext.get::<Number>(), Some(&Number(10)));
+ }
+}
diff --git a/vendor/clap_builder/src/builder/mod.rs b/vendor/clap_builder/src/builder/mod.rs
index 098ad576e..495c84587 100644
--- a/vendor/clap_builder/src/builder/mod.rs
+++ b/vendor/clap_builder/src/builder/mod.rs
@@ -7,6 +7,7 @@ mod arg_group;
mod arg_predicate;
mod arg_settings;
mod command;
+mod ext;
mod os_str;
mod possible_value;
mod range;
@@ -34,6 +35,8 @@ pub use range::ValueRange;
pub use resettable::IntoResettable;
pub use resettable::Resettable;
pub use styled_str::StyledStr;
+#[cfg(feature = "unstable-styles")]
+pub use styled_str::Styles;
pub use value_hint::ValueHint;
pub use value_parser::_AutoValueParser;
pub use value_parser::via_prelude;
@@ -58,3 +61,6 @@ pub use value_parser::_AnonymousValueParser;
pub(crate) use self::str::Inner as StrInner;
pub(crate) use action::CountType;
pub(crate) use arg_settings::{ArgFlags, ArgSettings};
+pub(crate) use command::AppTag;
+#[cfg(not(feature = "unstable-styles"))]
+pub(crate) use styled_str::Styles;
diff --git a/vendor/clap_builder/src/builder/styled_str.rs b/vendor/clap_builder/src/builder/styled_str.rs
index 94c838aaa..e4acc63ff 100644
--- a/vendor/clap_builder/src/builder/styled_str.rs
+++ b/vendor/clap_builder/src/builder/styled_str.rs
@@ -33,39 +33,14 @@ impl StyledStr {
self.0.as_str()
}
- pub(crate) fn header(&mut self, msg: impl Into<String>) {
- self.stylize(Style::Header, msg.into());
- }
-
- pub(crate) fn literal(&mut self, msg: impl Into<String>) {
- self.stylize(Style::Literal, msg.into());
- }
-
- pub(crate) fn placeholder(&mut self, msg: impl Into<String>) {
- self.stylize(Style::Placeholder, msg.into());
- }
-
- #[cfg_attr(not(feature = "error-context"), allow(dead_code))]
- pub(crate) fn good(&mut self, msg: impl Into<String>) {
- self.stylize(Style::Good, msg.into());
- }
-
- #[cfg_attr(not(feature = "error-context"), allow(dead_code))]
- pub(crate) fn warning(&mut self, msg: impl Into<String>) {
- self.stylize(Style::Warning, msg.into());
- }
-
- pub(crate) fn error(&mut self, msg: impl Into<String>) {
- self.stylize(Style::Error, msg.into());
- }
-
- #[allow(dead_code)]
- pub(crate) fn hint(&mut self, msg: impl Into<String>) {
- self.stylize(Style::Hint, msg.into());
+ /// May allow the compiler to consolidate the `Drop`s for `msg`, reducing code size compared to
+ /// `styled.push_str(&msg)`
+ pub(crate) fn push_string(&mut self, msg: String) {
+ self.0.push_str(&msg);
}
- pub(crate) fn none(&mut self, msg: impl Into<String>) {
- self.0.push_str(&msg.into());
+ pub(crate) fn push_str(&mut self, msg: &str) {
+ self.0.push_str(msg);
}
pub(crate) fn trim(&mut self) {
@@ -122,21 +97,6 @@ impl StyledStr {
self.0 = new;
}
- #[cfg(feature = "color")]
- fn stylize(&mut self, style: Style, msg: String) {
- if !msg.is_empty() {
- use std::fmt::Write as _;
-
- let style = style.as_style();
- let _ = write!(self.0, "{}{}{}", style.render(), msg, style.render_reset());
- }
- }
-
- #[cfg(not(feature = "color"))]
- fn stylize(&mut self, _style: Style, msg: String) {
- self.0.push_str(&msg);
- }
-
#[inline(never)]
#[cfg(feature = "help")]
pub(crate) fn display_width(&self) -> usize {
@@ -194,7 +154,7 @@ impl From<std::string::String> for StyledStr {
impl From<&'_ std::string::String> for StyledStr {
fn from(name: &'_ std::string::String) -> Self {
let mut styled = StyledStr::new();
- styled.none(name);
+ styled.push_str(name);
styled
}
}
@@ -202,7 +162,7 @@ impl From<&'_ std::string::String> for StyledStr {
impl From<&'static str> for StyledStr {
fn from(name: &'static str) -> Self {
let mut styled = StyledStr::new();
- styled.none(name);
+ styled.push_str(name);
styled
}
}
@@ -238,28 +198,163 @@ impl std::fmt::Display for StyledStr {
}
}
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub(crate) enum Style {
- Header,
- Literal,
- Placeholder,
- Good,
- Warning,
- Error,
- Hint,
+/// Terminal styling definitions
+#[derive(Clone, Debug)]
+#[allow(missing_copy_implementations)] // Large enough type that I want an explicit `clone()` for now
+pub struct Styles {
+ header: anstyle::Style,
+ error: anstyle::Style,
+ usage: anstyle::Style,
+ literal: anstyle::Style,
+ placeholder: anstyle::Style,
+ valid: anstyle::Style,
+ invalid: anstyle::Style,
}
-impl Style {
- #[cfg(feature = "color")]
- fn as_style(&self) -> anstyle::Style {
- match self {
- Style::Header => (anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE).into(),
- Style::Literal => anstyle::Effects::BOLD.into(),
- Style::Placeholder => anstyle::Style::default(),
- Style::Good => anstyle::AnsiColor::Green.on_default(),
- Style::Warning => anstyle::AnsiColor::Yellow.on_default(),
- Style::Error => anstyle::AnsiColor::Red.on_default() | anstyle::Effects::BOLD,
- Style::Hint => anstyle::Effects::DIMMED.into(),
+impl Styles {
+ /// No terminal styling
+ pub const fn plain() -> Self {
+ Self {
+ header: anstyle::Style::new(),
+ error: anstyle::Style::new(),
+ usage: anstyle::Style::new(),
+ literal: anstyle::Style::new(),
+ placeholder: anstyle::Style::new(),
+ valid: anstyle::Style::new(),
+ invalid: anstyle::Style::new(),
+ }
+ }
+
+ /// Default terminal styling
+ pub const fn styled() -> Self {
+ #[cfg(feature = "color")]
+ {
+ Self {
+ header: anstyle::Style::new().bold().underline(),
+ error: anstyle::Style::new()
+ .fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Red)))
+ .bold(),
+ usage: anstyle::Style::new().bold().underline(),
+ literal: anstyle::Style::new().bold(),
+ placeholder: anstyle::Style::new(),
+ valid: anstyle::Style::new()
+ .fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Green))),
+ invalid: anstyle::Style::new()
+ .fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Yellow))),
+ }
+ }
+ #[cfg(not(feature = "color"))]
+ {
+ Self::plain()
}
}
+
+ /// General Heading style, e.g. [`help_heading`][crate::Arg::help_heading]
+ #[inline]
+ pub const fn header(mut self, style: anstyle::Style) -> Self {
+ self.header = style;
+ self
+ }
+
+ /// Error heading
+ #[inline]
+ pub const fn error(mut self, style: anstyle::Style) -> Self {
+ self.error = style;
+ self
+ }
+
+ /// Usage heading
+ #[inline]
+ pub const fn usage(mut self, style: anstyle::Style) -> Self {
+ self.usage = style;
+ self
+ }
+
+ /// Literal command-line syntax, e.g. `--help`
+ #[inline]
+ pub const fn literal(mut self, style: anstyle::Style) -> Self {
+ self.literal = style;
+ self
+ }
+
+ /// Descriptions within command-line syntax, e.g. [`value_name`][crate::Arg::value_name]
+ #[inline]
+ pub const fn placeholder(mut self, style: anstyle::Style) -> Self {
+ self.placeholder = style;
+ self
+ }
+
+ /// Highlight suggested usage
+ #[inline]
+ pub const fn valid(mut self, style: anstyle::Style) -> Self {
+ self.valid = style;
+ self
+ }
+
+ /// Highlight invalid usage
+ #[inline]
+ pub const fn invalid(mut self, style: anstyle::Style) -> Self {
+ self.invalid = style;
+ self
+ }
+}
+
+/// Reflection
+impl Styles {
+ /// General Heading style, e.g. [`help_heading`][crate::Arg::help_heading]
+ #[inline(always)]
+ pub const fn get_header(&self) -> &anstyle::Style {
+ &self.header
+ }
+
+ /// Error heading
+ #[inline(always)]
+ pub const fn get_error(&self) -> &anstyle::Style {
+ &self.error
+ }
+
+ /// Usage heading
+ #[inline(always)]
+ pub const fn get_usage(&self) -> &anstyle::Style {
+ &self.usage
+ }
+
+ /// Literal command-line syntax, e.g. `--help`
+ #[inline(always)]
+ pub const fn get_literal(&self) -> &anstyle::Style {
+ &self.literal
+ }
+
+ /// Descriptions within command-line syntax, e.g. [`value_name`][crate::Arg::value_name]
+ #[inline(always)]
+ pub const fn get_placeholder(&self) -> &anstyle::Style {
+ &self.placeholder
+ }
+
+ /// Highlight suggested usage
+ #[inline(always)]
+ pub const fn get_valid(&self) -> &anstyle::Style {
+ &self.valid
+ }
+
+ /// Highlight invalid usage
+ #[inline(always)]
+ pub const fn get_invalid(&self) -> &anstyle::Style {
+ &self.invalid
+ }
+}
+
+impl super::AppTag for Styles {}
+
+impl Default for Styles {
+ fn default() -> Self {
+ Self::styled()
+ }
+}
+
+impl Default for &'_ Styles {
+ fn default() -> Self {
+ const STYLES: Styles = Styles::styled();
+ &STYLES
+ }
}
diff --git a/vendor/clap_builder/src/builder/value_parser.rs b/vendor/clap_builder/src/builder/value_parser.rs
index d4a1a7ab7..24631ce7c 100644
--- a/vendor/clap_builder/src/builder/value_parser.rs
+++ b/vendor/clap_builder/src/builder/value_parser.rs
@@ -1,8 +1,8 @@
use std::convert::TryInto;
use std::ops::RangeBounds;
-use crate::parser::AnyValue;
-use crate::parser::AnyValueId;
+use crate::util::AnyValue;
+use crate::util::AnyValueId;
/// Parse/validate argument values
///
diff --git a/vendor/clap_builder/src/error/format.rs b/vendor/clap_builder/src/error/format.rs
index 5ada0abe5..b5f0c1264 100644
--- a/vendor/clap_builder/src/error/format.rs
+++ b/vendor/clap_builder/src/error/format.rs
@@ -5,6 +5,7 @@
use crate::builder::Command;
use crate::builder::StyledStr;
+use crate::builder::Styles;
#[cfg(feature = "error-context")]
use crate::error::ContextKind;
#[cfg(feature = "error-context")]
@@ -29,16 +30,19 @@ pub struct KindFormatter;
impl ErrorFormatter for KindFormatter {
fn format_error(error: &crate::error::Error<Self>) -> StyledStr {
+ use std::fmt::Write as _;
+ let styles = &error.inner.styles;
+
let mut styled = StyledStr::new();
- start_error(&mut styled);
+ start_error(&mut styled, styles);
if let Some(msg) = error.kind().as_str() {
- styled.none(msg.to_owned());
+ styled.push_str(msg);
} else if let Some(source) = error.inner.source.as_ref() {
- styled.none(source.to_string());
+ let _ = write!(styled, "{}", source);
} else {
- styled.none("unknown cause");
+ styled.push_str("unknown cause");
}
- styled.none("\n");
+ styled.push_str("\n");
styled
}
}
@@ -53,53 +57,60 @@ pub struct RichFormatter;
#[cfg(feature = "error-context")]
impl ErrorFormatter for RichFormatter {
fn format_error(error: &crate::error::Error<Self>) -> StyledStr {
+ use std::fmt::Write as _;
+ let styles = &error.inner.styles;
+ let valid = &styles.get_valid();
+
let mut styled = StyledStr::new();
- start_error(&mut styled);
+ start_error(&mut styled, styles);
- if !write_dynamic_context(error, &mut styled) {
+ if !write_dynamic_context(error, &mut styled, styles) {
if let Some(msg) = error.kind().as_str() {
- styled.none(msg.to_owned());
+ styled.push_str(msg);
} else if let Some(source) = error.inner.source.as_ref() {
- styled.none(source.to_string());
+ let _ = write!(styled, "{}", source);
} else {
- styled.none("unknown cause");
+ styled.push_str("unknown cause");
}
}
let mut suggested = false;
if let Some(valid) = error.get(ContextKind::SuggestedSubcommand) {
- styled.none("\n");
+ styled.push_str("\n");
if !suggested {
- styled.none("\n");
+ styled.push_str("\n");
suggested = true;
}
- did_you_mean(&mut styled, "subcommand", valid);
+ did_you_mean(&mut styled, styles, "subcommand", valid);
}
if let Some(valid) = error.get(ContextKind::SuggestedArg) {
- styled.none("\n");
+ styled.push_str("\n");
if !suggested {
- styled.none("\n");
+ styled.push_str("\n");
suggested = true;
}
- did_you_mean(&mut styled, "argument", valid);
+ did_you_mean(&mut styled, styles, "argument", valid);
}
if let Some(valid) = error.get(ContextKind::SuggestedValue) {
- styled.none("\n");
+ styled.push_str("\n");
if !suggested {
- styled.none("\n");
+ styled.push_str("\n");
suggested = true;
}
- did_you_mean(&mut styled, "value", valid);
+ did_you_mean(&mut styled, styles, "value", valid);
}
let suggestions = error.get(ContextKind::Suggested);
if let Some(ContextValue::StyledStrs(suggestions)) = suggestions {
if !suggested {
- styled.none("\n");
+ styled.push_str("\n");
}
for suggestion in suggestions {
- styled.none("\n");
- styled.none(TAB);
- styled.good("tip: ");
+ let _ = write!(
+ styled,
+ "\n{TAB}{}tip:{} ",
+ valid.render(),
+ valid.render_reset()
+ );
styled.push_styled(suggestion);
}
}
@@ -109,20 +120,30 @@ impl ErrorFormatter for RichFormatter {
put_usage(&mut styled, usage);
}
- try_help(&mut styled, error.inner.help_flag);
+ try_help(&mut styled, styles, error.inner.help_flag);
styled
}
}
-fn start_error(styled: &mut StyledStr) {
- styled.error("error:");
- styled.none(" ");
+fn start_error(styled: &mut StyledStr, styles: &Styles) {
+ use std::fmt::Write as _;
+ let error = &styles.get_error();
+ let _ = write!(styled, "{}error:{} ", error.render(), error.render_reset());
}
#[must_use]
#[cfg(feature = "error-context")]
-fn write_dynamic_context(error: &crate::error::Error, styled: &mut StyledStr) -> bool {
+fn write_dynamic_context(
+ error: &crate::error::Error,
+ styled: &mut StyledStr,
+ styles: &Styles,
+) -> bool {
+ use std::fmt::Write as _;
+ let valid = styles.get_valid();
+ let invalid = styles.get_invalid();
+ let literal = styles.get_literal();
+
match error.kind() {
ErrorKind::ArgumentConflict => {
let invalid_arg = error.get(ContextKind::InvalidArg);
@@ -131,30 +152,42 @@ fn write_dynamic_context(error: &crate::error::Error, styled: &mut StyledStr) ->
(invalid_arg, prior_arg)
{
if ContextValue::String(invalid_arg.clone()) == *prior_arg {
- styled.none("the argument '");
- styled.warning(invalid_arg);
- styled.none("' cannot be used multiple times");
+ let _ = write!(
+ styled,
+ "the argument '{}{invalid_arg}{}' cannot be used multiple times",
+ invalid.render(),
+ invalid.render_reset()
+ );
} else {
- styled.none("the argument '");
- styled.warning(invalid_arg);
- styled.none("' cannot be used with");
+ let _ = write!(
+ styled,
+ "the argument '{}{invalid_arg}{}' cannot be used with",
+ invalid.render(),
+ invalid.render_reset()
+ );
match prior_arg {
ContextValue::Strings(values) => {
- styled.none(":");
+ styled.push_str(":");
for v in values {
- styled.none("\n");
- styled.none(TAB);
- styled.warning(&**v);
+ let _ = write!(
+ styled,
+ "\n{TAB}{}{v}{}",
+ invalid.render(),
+ invalid.render_reset()
+ );
}
}
ContextValue::String(value) => {
- styled.none(" '");
- styled.warning(value);
- styled.none("'");
+ let _ = write!(
+ styled,
+ " '{}{value}{}'",
+ invalid.render(),
+ invalid.render_reset()
+ );
}
_ => {
- styled.none(" one or more of the other specified arguments");
+ styled.push_str(" one or more of the other specified arguments");
}
}
}
@@ -166,9 +199,12 @@ fn write_dynamic_context(error: &crate::error::Error, styled: &mut StyledStr) ->
ErrorKind::NoEquals => {
let invalid_arg = error.get(ContextKind::InvalidArg);
if let Some(ContextValue::String(invalid_arg)) = invalid_arg {
- styled.none("equal sign is needed when assigning values to '");
- styled.warning(invalid_arg);
- styled.none("'");
+ let _ = write!(
+ styled,
+ "equal sign is needed when assigning values to '{}{invalid_arg}{}'",
+ invalid.render(),
+ invalid.render_reset()
+ );
true
} else {
false
@@ -183,31 +219,46 @@ fn write_dynamic_context(error: &crate::error::Error, styled: &mut StyledStr) ->
) = (invalid_arg, invalid_value)
{
if invalid_value.is_empty() {
- styled.none("a value is required for '");
- styled.warning(invalid_arg);
- styled.none("' but none was supplied");
+ let _ = write!(
+ styled,
+ "a value is required for '{}{invalid_arg}{}' but none was supplied",
+ invalid.render(),
+ invalid.render_reset()
+ );
} else {
- styled.none("invalid value '");
- styled.none(invalid_value);
- styled.none("' for '");
- styled.warning(invalid_arg);
- styled.none("'");
+ let _ = write!(
+ styled,
+ "invalid value '{}{invalid_value}{}' for '{}{invalid_arg}{}'",
+ invalid.render(),
+ invalid.render_reset(),
+ literal.render(),
+ literal.render_reset()
+ );
}
let possible_values = error.get(ContextKind::ValidValue);
if let Some(ContextValue::Strings(possible_values)) = possible_values {
if !possible_values.is_empty() {
- styled.none("\n");
- styled.none(TAB);
- styled.none("[possible values: ");
+ let _ = write!(styled, "\n{TAB}[possible values: ");
if let Some((last, elements)) = possible_values.split_last() {
for v in elements {
- styled.good(escape(v));
- styled.none(", ");
+ let _ = write!(
+ styled,
+ "{}{}{}, ",
+ valid.render(),
+ Escape(v),
+ valid.render_reset()
+ );
}
- styled.good(escape(last));
+ let _ = write!(
+ styled,
+ "{}{}{}",
+ valid.render(),
+ Escape(last),
+ valid.render_reset()
+ );
}
- styled.none("]");
+ styled.push_str("]");
}
}
true
@@ -218,9 +269,12 @@ fn write_dynamic_context(error: &crate::error::Error, styled: &mut StyledStr) ->
ErrorKind::InvalidSubcommand => {
let invalid_sub = error.get(ContextKind::InvalidSubcommand);
if let Some(ContextValue::String(invalid_sub)) = invalid_sub {
- styled.none("unrecognized subcommand '");
- styled.warning(invalid_sub);
- styled.none("'");
+ let _ = write!(
+ styled,
+ "unrecognized subcommand '{}{invalid_sub}{}'",
+ invalid.render(),
+ invalid.render_reset()
+ );
true
} else {
false
@@ -229,11 +283,14 @@ fn write_dynamic_context(error: &crate::error::Error, styled: &mut StyledStr) ->
ErrorKind::MissingRequiredArgument => {
let invalid_arg = error.get(ContextKind::InvalidArg);
if let Some(ContextValue::Strings(invalid_arg)) = invalid_arg {
- styled.none("the following required arguments were not provided:");
+ styled.push_str("the following required arguments were not provided:");
for v in invalid_arg {
- styled.none("\n");
- styled.none(TAB);
- styled.good(&**v);
+ let _ = write!(
+ styled,
+ "\n{TAB}{}{v}{}",
+ valid.render(),
+ valid.render_reset()
+ );
}
true
} else {
@@ -243,24 +300,36 @@ fn write_dynamic_context(error: &crate::error::Error, styled: &mut StyledStr) ->
ErrorKind::MissingSubcommand => {
let invalid_sub = error.get(ContextKind::InvalidSubcommand);
if let Some(ContextValue::String(invalid_sub)) = invalid_sub {
- styled.none("'");
- styled.warning(invalid_sub);
- styled.none("' requires a subcommand but one was not provided");
+ let _ = write!(
+ styled,
+ "'{}{invalid_sub}{}' requires a subcommand but one was not provided",
+ invalid.render(),
+ invalid.render_reset()
+ );
let possible_values = error.get(ContextKind::ValidSubcommand);
if let Some(ContextValue::Strings(possible_values)) = possible_values {
if !possible_values.is_empty() {
- styled.none("\n");
- styled.none(TAB);
- styled.none("[subcommands: ");
+ let _ = write!(styled, "\n{TAB}[subcommands: ");
if let Some((last, elements)) = possible_values.split_last() {
for v in elements {
- styled.good(escape(v));
- styled.none(", ");
+ let _ = write!(
+ styled,
+ "{}{}{}, ",
+ valid.render(),
+ Escape(v),
+ valid.render_reset()
+ );
}
- styled.good(escape(last));
+ let _ = write!(
+ styled,
+ "{}{}{}",
+ valid.render(),
+ Escape(last),
+ valid.render_reset()
+ );
}
- styled.none("]");
+ styled.push_str("]");
}
}
@@ -278,11 +347,14 @@ fn write_dynamic_context(error: &crate::error::Error, styled: &mut StyledStr) ->
Some(ContextValue::String(invalid_value)),
) = (invalid_arg, invalid_value)
{
- styled.none("unexpected value '");
- styled.warning(invalid_value);
- styled.none("' for '");
- styled.warning(invalid_arg);
- styled.none("' found; no more were expected");
+ let _ = write!(
+ styled,
+ "unexpected value '{}{invalid_value}{}' for '{}{invalid_arg}{}' found; no more were expected",
+ invalid.render(),
+ invalid.render_reset(),
+ literal.render(),
+ literal.render_reset(),
+ );
true
} else {
false
@@ -299,12 +371,16 @@ fn write_dynamic_context(error: &crate::error::Error, styled: &mut StyledStr) ->
) = (invalid_arg, actual_num_values, min_values)
{
let were_provided = singular_or_plural(*actual_num_values as usize);
- styled.warning(min_values.to_string());
- styled.none(" more values required by '");
- styled.warning(invalid_arg);
- styled.none("'; only ");
- styled.warning(actual_num_values.to_string());
- styled.none(were_provided);
+ let _ = write!(
+ styled,
+ "{}{min_values}{} more values required by '{}{invalid_arg}{}'; only {}{actual_num_values}{}{were_provided}",
+ valid.render(),
+ valid.render_reset(),
+ literal.render(),
+ literal.render_reset(),
+ invalid.render(),
+ invalid.render_reset(),
+ );
true
} else {
false
@@ -318,15 +394,16 @@ fn write_dynamic_context(error: &crate::error::Error, styled: &mut StyledStr) ->
Some(ContextValue::String(invalid_value)),
) = (invalid_arg, invalid_value)
{
- styled.none("invalid value '");
- styled.warning(invalid_value);
- styled.none("' for '");
- styled.warning(invalid_arg);
+ let _ = write!(
+ styled,
+ "invalid value '{}{invalid_value}{}' for '{}{invalid_arg}{}'",
+ invalid.render(),
+ invalid.render_reset(),
+ literal.render(),
+ literal.render_reset(),
+ );
if let Some(source) = error.inner.source.as_deref() {
- styled.none("': ");
- styled.none(source.to_string());
- } else {
- styled.none("'");
+ let _ = write!(styled, ": {}", source);
}
true
} else {
@@ -344,12 +421,16 @@ fn write_dynamic_context(error: &crate::error::Error, styled: &mut StyledStr) ->
) = (invalid_arg, actual_num_values, num_values)
{
let were_provided = singular_or_plural(*actual_num_values as usize);
- styled.warning(num_values.to_string());
- styled.none(" values required for '");
- styled.warning(invalid_arg);
- styled.none("' but ");
- styled.warning(actual_num_values.to_string());
- styled.none(were_provided);
+ let _ = write!(
+ styled,
+ "{}{num_values}{} values required for '{}{invalid_arg}{}' but {}{actual_num_values}{}{were_provided}",
+ valid.render(),
+ valid.render_reset(),
+ literal.render(),
+ literal.render_reset(),
+ invalid.render(),
+ invalid.render_reset(),
+ );
true
} else {
false
@@ -358,9 +439,12 @@ fn write_dynamic_context(error: &crate::error::Error, styled: &mut StyledStr) ->
ErrorKind::UnknownArgument => {
let invalid_arg = error.get(ContextKind::InvalidArg);
if let Some(ContextValue::String(invalid_arg)) = invalid_arg {
- styled.none("unexpected argument '");
- styled.warning(invalid_arg.to_string());
- styled.none("' found");
+ let _ = write!(
+ styled,
+ "unexpected argument '{}{invalid_arg}{}' found",
+ invalid.render(),
+ invalid.render_reset(),
+ );
true
} else {
false
@@ -376,17 +460,18 @@ fn write_dynamic_context(error: &crate::error::Error, styled: &mut StyledStr) ->
pub(crate) fn format_error_message(
message: &str,
+ styles: &Styles,
cmd: Option<&Command>,
usage: Option<&StyledStr>,
) -> StyledStr {
let mut styled = StyledStr::new();
- start_error(&mut styled);
- styled.none(message);
+ start_error(&mut styled, styles);
+ styled.push_str(message);
if let Some(usage) = usage {
put_usage(&mut styled, usage);
}
if let Some(cmd) = cmd {
- try_help(&mut styled, get_help_flag(cmd));
+ try_help(&mut styled, styles, get_help_flag(cmd));
}
styled
}
@@ -401,7 +486,7 @@ fn singular_or_plural(n: usize) -> &'static str {
}
fn put_usage(styled: &mut StyledStr, usage: &StyledStr) {
- styled.none("\n\n");
+ styled.push_str("\n\n");
styled.push_styled(usage);
}
@@ -415,52 +500,66 @@ pub(crate) fn get_help_flag(cmd: &Command) -> Option<&'static str> {
}
}
-fn try_help(styled: &mut StyledStr, help: Option<&str>) {
+fn try_help(styled: &mut StyledStr, styles: &Styles, help: Option<&str>) {
if let Some(help) = help {
- styled.none("\n\nFor more information, try '");
- styled.literal(help.to_owned());
- styled.none("'.\n");
+ use std::fmt::Write as _;
+ let literal = &styles.get_literal();
+ let _ = write!(
+ styled,
+ "\n\nFor more information, try '{}{help}{}'.\n",
+ literal.render(),
+ literal.render_reset()
+ );
} else {
- styled.none("\n");
+ styled.push_str("\n");
}
}
#[cfg(feature = "error-context")]
-fn did_you_mean(styled: &mut StyledStr, context: &str, valid: &ContextValue) {
- styled.none(TAB);
- styled.good("tip:");
+fn did_you_mean(styled: &mut StyledStr, styles: &Styles, context: &str, valid: &ContextValue) {
+ use std::fmt::Write as _;
+
+ let _ = write!(
+ styled,
+ "{TAB}{}tip:{}",
+ styles.get_valid().render(),
+ styles.get_valid().render_reset()
+ );
if let ContextValue::String(valid) = valid {
- styled.none(" a similar ");
- styled.none(context);
- styled.none(" exists: '");
- styled.good(valid);
- styled.none("'");
+ let _ = write!(
+ styled,
+ " a similar {context} exists: '{}{valid}{}'",
+ styles.get_valid().render(),
+ styles.get_valid().render_reset()
+ );
} else if let ContextValue::Strings(valid) = valid {
if valid.len() == 1 {
- styled.none(" a similar ");
- styled.none(context);
- styled.none(" exists: ");
+ let _ = write!(styled, " a similar {context} exists: ",);
} else {
- styled.none(" some similar ");
- styled.none(context);
- styled.none("s exist: ");
+ let _ = write!(styled, " some similar {context}s exist: ",);
}
for (i, valid) in valid.iter().enumerate() {
if i != 0 {
- styled.none(", ");
+ styled.push_str(", ");
}
- styled.none("'");
- styled.good(valid);
- styled.none("'");
+ let _ = write!(
+ styled,
+ "'{}{valid}{}'",
+ styles.get_valid().render(),
+ styles.get_valid().render_reset()
+ );
}
}
}
-fn escape(s: impl AsRef<str>) -> String {
- let s = s.as_ref();
- if s.contains(char::is_whitespace) {
- format!("{s:?}")
- } else {
- s.to_owned()
+struct Escape<'s>(&'s str);
+
+impl<'s> std::fmt::Display for Escape<'s> {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ if self.0.contains(char::is_whitespace) {
+ std::fmt::Debug::fmt(self.0, f)
+ } else {
+ self.0.fmt(f)
+ }
}
}
diff --git a/vendor/clap_builder/src/error/mod.rs b/vendor/clap_builder/src/error/mod.rs
index 52f17bd56..cb3629669 100644
--- a/vendor/clap_builder/src/error/mod.rs
+++ b/vendor/clap_builder/src/error/mod.rs
@@ -18,6 +18,7 @@ use std::{
// Internal
use crate::builder::StyledStr;
+use crate::builder::Styles;
use crate::output::fmt::Colorizer;
use crate::output::fmt::Stream;
use crate::parser::features::suggestions;
@@ -69,6 +70,7 @@ struct ErrorInner {
message: Option<Message>,
source: Option<Box<dyn error::Error + Send + Sync>>,
help_flag: Option<&'static str>,
+ styles: Styles,
color_when: ColorChoice,
color_help_when: ColorChoice,
backtrace: Option<Backtrace>,
@@ -132,6 +134,7 @@ impl<F: ErrorFormatter> Error<F> {
message: None,
source: None,
help_flag: None,
+ styles: Styles::plain(),
color_when: ColorChoice::Never,
color_help_when: ColorChoice::Never,
backtrace: Backtrace::new(),
@@ -144,7 +147,8 @@ impl<F: ErrorFormatter> Error<F> {
///
/// Generally, this is used with [`Error::new`]
pub fn with_cmd(self, cmd: &Command) -> Self {
- self.set_color(cmd.get_color())
+ self.set_styles(cmd.get_styles().clone())
+ .set_color(cmd.get_color())
.set_colored_help(cmd.color_help())
.set_help_flag(format::get_help_flag(cmd))
}
@@ -295,6 +299,11 @@ impl<F: ErrorFormatter> Error<F> {
self
}
+ pub(crate) fn set_styles(mut self, styles: Styles) -> Self {
+ self.inner.styles = styles;
+ self
+ }
+
pub(crate) fn set_color(mut self, color_when: ColorChoice) -> Self {
self.inner.color_when = color_when;
self
@@ -434,18 +443,23 @@ impl<F: ErrorFormatter> Error<F> {
name: String,
usage: Option<StyledStr>,
) -> Self {
+ use std::fmt::Write as _;
+ let styles = cmd.get_styles();
+ let invalid = &styles.get_invalid();
+ let valid = &styles.get_valid();
let mut err = Self::new(ErrorKind::InvalidSubcommand).with_cmd(cmd);
#[cfg(feature = "error-context")]
{
let mut styled_suggestion = StyledStr::new();
- styled_suggestion.none("to pass '");
- styled_suggestion.warning(&subcmd);
- styled_suggestion.none("' as a value, use '");
- styled_suggestion.good(name);
- styled_suggestion.good(" -- ");
- styled_suggestion.good(&subcmd);
- styled_suggestion.none("'");
+ let _ = write!(
+ styled_suggestion,
+ "to pass '{}{subcmd}{}' as a value, use '{}{name} -- {subcmd}{}'",
+ invalid.render(),
+ invalid.render_reset(),
+ valid.render(),
+ valid.render_reset()
+ );
err = err.extend_context_unchecked([
(ContextKind::InvalidSubcommand, ContextValue::String(subcmd)),
@@ -661,6 +675,10 @@ impl<F: ErrorFormatter> Error<F> {
suggested_trailing_arg: bool,
usage: Option<StyledStr>,
) -> Self {
+ use std::fmt::Write as _;
+ let styles = cmd.get_styles();
+ let invalid = &styles.get_invalid();
+ let valid = &styles.get_valid();
let mut err = Self::new(ErrorKind::UnknownArgument).with_cmd(cmd);
#[cfg(feature = "error-context")]
@@ -668,12 +686,14 @@ impl<F: ErrorFormatter> Error<F> {
let mut suggestions = vec![];
if suggested_trailing_arg {
let mut styled_suggestion = StyledStr::new();
- styled_suggestion.none("to pass '");
- styled_suggestion.warning(&arg);
- styled_suggestion.none("' as a value, use '");
- styled_suggestion.good("-- ");
- styled_suggestion.good(&arg);
- styled_suggestion.none("'");
+ let _ = write!(
+ styled_suggestion,
+ "to pass '{}{arg}{}' as a value, use '{}-- {arg}{}'",
+ invalid.render(),
+ invalid.render_reset(),
+ valid.render(),
+ valid.render_reset()
+ );
suggestions.push(styled_suggestion);
}
@@ -686,12 +706,12 @@ impl<F: ErrorFormatter> Error<F> {
match did_you_mean {
Some((flag, Some(sub))) => {
let mut styled_suggestion = StyledStr::new();
- styled_suggestion.none("'");
- styled_suggestion.good(sub);
- styled_suggestion.none(" ");
- styled_suggestion.good("--");
- styled_suggestion.good(flag);
- styled_suggestion.none("' exists");
+ let _ = write!(
+ styled_suggestion,
+ "'{}{sub} --{flag}{}' exists",
+ valid.render(),
+ valid.render_reset()
+ );
suggestions.push(styled_suggestion);
}
Some((flag, None)) => {
@@ -718,16 +738,23 @@ impl<F: ErrorFormatter> Error<F> {
arg: String,
usage: Option<StyledStr>,
) -> Self {
+ use std::fmt::Write as _;
+ let styles = cmd.get_styles();
+ let invalid = &styles.get_invalid();
+ let valid = &styles.get_valid();
let mut err = Self::new(ErrorKind::UnknownArgument).with_cmd(cmd);
#[cfg(feature = "error-context")]
{
let mut styled_suggestion = StyledStr::new();
- styled_suggestion.none("subcommand '");
- styled_suggestion.good(&arg);
- styled_suggestion.none("' exists; to use it, remove the '");
- styled_suggestion.warning("--");
- styled_suggestion.none("' before it");
+ let _ = write!(
+ styled_suggestion,
+ "subcommand '{}{arg}{}' exists; to use it, remove the '{}--{}' before it",
+ valid.render(),
+ valid.render_reset(),
+ invalid.render(),
+ invalid.render_reset()
+ );
err = err.extend_context_unchecked([
(ContextKind::InvalidArg, ContextValue::String(arg)),
@@ -747,7 +774,7 @@ impl<F: ErrorFormatter> Error<F> {
fn formatted(&self) -> Cow<'_, StyledStr> {
if let Some(message) = self.inner.message.as_ref() {
- message.formatted()
+ message.formatted(&self.inner.styles)
} else {
let styled = F::format_error(self);
Cow::Owned(styled)
@@ -806,7 +833,12 @@ impl Message {
let mut message = String::new();
std::mem::swap(s, &mut message);
- let styled = format::format_error_message(&message, Some(cmd), usage.as_ref());
+ let styled = format::format_error_message(
+ &message,
+ cmd.get_styles(),
+ Some(cmd),
+ usage.as_ref(),
+ );
*self = Self::Formatted(styled);
}
@@ -814,10 +846,10 @@ impl Message {
}
}
- fn formatted(&self) -> Cow<StyledStr> {
+ fn formatted(&self, styles: &Styles) -> Cow<StyledStr> {
match self {
Message::Raw(s) => {
- let styled = format::format_error_message(s, None, None);
+ let styled = format::format_error_message(s, styles, None, None);
Cow::Owned(styled)
}
diff --git a/vendor/clap_builder/src/lib.rs b/vendor/clap_builder/src/lib.rs
index a8c1201e0..97c32c141 100644
--- a/vendor/clap_builder/src/lib.rs
+++ b/vendor/clap_builder/src/lib.rs
@@ -16,6 +16,10 @@
clippy::single_char_pattern
)]
#![forbid(unsafe_code)]
+// Wanting consistency in our calls
+#![allow(clippy::write_with_newline)]
+// Gets in the way of logging
+#![allow(clippy::let_and_return)]
// HACK https://github.com/rust-lang/rust-clippy/issues/7290
#![allow(clippy::single_component_path_imports)]
#![allow(clippy::branches_sharing_code)]
diff --git a/vendor/clap_builder/src/macros.rs b/vendor/clap_builder/src/macros.rs
index 82a881198..59135e212 100644
--- a/vendor/clap_builder/src/macros.rs
+++ b/vendor/clap_builder/src/macros.rs
@@ -628,12 +628,13 @@ macro_rules! impl_settings {
#[cfg(feature = "debug")]
macro_rules! debug {
($($arg:tt)*) => ({
- let prefix = format!("[{:>w$}] \t", module_path!(), w = 28);
+ use std::fmt::Write as _;
+ let hint = anstyle::Style::new().dimmed();
+
+ let module_path = module_path!();
let body = format!($($arg)*);
let mut styled = $crate::builder::StyledStr::new();
- styled.hint(prefix);
- styled.hint(body);
- styled.none("\n");
+ let _ = write!(styled, "{}[{module_path:>28}]{body}{}\n", hint.render(), hint.render_reset());
let color = $crate::output::fmt::Colorizer::new($crate::output::fmt::Stream::Stderr, $crate::ColorChoice::Auto).with_content(styled);
let _ = color.print();
})
diff --git a/vendor/clap_builder/src/output/help.rs b/vendor/clap_builder/src/output/help.rs
index 4921f5f71..410616eb1 100644
--- a/vendor/clap_builder/src/output/help.rs
+++ b/vendor/clap_builder/src/output/help.rs
@@ -33,5 +33,5 @@ pub(crate) fn write_help(writer: &mut StyledStr, cmd: &Command, usage: &Usage<'_
// Remove any extra lines caused by book keeping
writer.trim();
// Ensure there is still a trailing newline
- writer.none("\n");
+ writer.push_str("\n");
}
diff --git a/vendor/clap_builder/src/output/help_template.rs b/vendor/clap_builder/src/output/help_template.rs
index cea9a7687..86a61169c 100644
--- a/vendor/clap_builder/src/output/help_template.rs
+++ b/vendor/clap_builder/src/output/help_template.rs
@@ -1,3 +1,8 @@
+// HACK: for rust 1.64 (1.68 doesn't need this since this is in lib.rs)
+//
+// Wanting consistency in our calls
+#![allow(clippy::write_with_newline)]
+
// Std
use std::borrow::Cow;
use std::cmp;
@@ -7,6 +12,7 @@ use std::usize;
use crate::builder::PossibleValue;
use crate::builder::Str;
use crate::builder::StyledStr;
+use crate::builder::Styles;
use crate::builder::{Arg, Command};
use crate::output::display_width;
use crate::output::wrap;
@@ -74,6 +80,7 @@ const DEFAULT_NO_ARGS_TEMPLATE: &str = "\
pub(crate) struct HelpTemplate<'cmd, 'writer> {
writer: &'writer mut StyledStr,
cmd: &'cmd Command,
+ styles: &'cmd Styles,
usage: &'cmd Usage<'cmd>,
next_line_help: bool,
term_w: usize,
@@ -112,6 +119,7 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
HelpTemplate {
writer,
cmd,
+ styles: cmd.get_styles(),
usage,
next_line_help,
term_w,
@@ -126,10 +134,11 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
/// [`Command::help_template`]: Command::help_template()
pub(crate) fn write_templated_help(&mut self, template: &str) {
debug!("HelpTemplate::write_templated_help");
+ use std::fmt::Write as _;
let mut parts = template.split('{');
if let Some(first) = parts.next() {
- self.none(first);
+ self.writer.push_str(first);
}
for part in parts {
if let Some((tag, rest)) = part.split_once('}') {
@@ -163,7 +172,12 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
self.write_about(true, true);
}
"usage-heading" => {
- self.header("Usage:");
+ let _ = write!(
+ self.writer,
+ "{}Usage:{}",
+ self.styles.get_usage().render(),
+ self.styles.get_usage().render_reset()
+ );
}
"usage" => {
self.writer.push_styled(
@@ -193,7 +207,7 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
self.write_subcommands(self.cmd);
}
"tab" => {
- self.none(TAB);
+ self.writer.push_str(TAB);
}
"after-help" => {
self.write_after_help();
@@ -202,12 +216,10 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
self.write_before_help();
}
_ => {
- self.none("{");
- self.none(tag);
- self.none("}");
+ let _ = write!(self.writer, "{{{tag}}}");
}
}
- self.none(rest);
+ self.writer.push_str(rest);
}
}
}
@@ -227,7 +239,7 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
.replace("{n}", "\n"),
self.term_w,
);
- self.none(&display_name);
+ self.writer.push_string(display_name);
}
/// Writes binary name of a Parser Object to the wrapped stream.
@@ -245,7 +257,7 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
} else {
wrap(&self.cmd.get_name().replace("{n}", "\n"), self.term_w)
};
- self.none(&bin_name);
+ self.writer.push_string(bin_name);
}
fn write_version(&mut self) {
@@ -254,18 +266,18 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
.get_version()
.or_else(|| self.cmd.get_long_version());
if let Some(output) = version {
- self.none(wrap(output, self.term_w));
+ self.writer.push_string(wrap(output, self.term_w));
}
}
fn write_author(&mut self, before_new_line: bool, after_new_line: bool) {
if let Some(author) = self.cmd.get_author() {
if before_new_line {
- self.none("\n");
+ self.writer.push_str("\n");
}
- self.none(wrap(author, self.term_w));
+ self.writer.push_string(wrap(author, self.term_w));
if after_new_line {
- self.none("\n");
+ self.writer.push_str("\n");
}
}
}
@@ -278,14 +290,14 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
};
if let Some(output) = about {
if before_new_line {
- self.none("\n");
+ self.writer.push_str("\n");
}
let mut output = output.clone();
output.replace_newline_var();
output.wrap(self.term_w);
self.writer.push_styled(&output);
if after_new_line {
- self.none("\n");
+ self.writer.push_str("\n");
}
}
}
@@ -304,7 +316,7 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
output.replace_newline_var();
output.wrap(self.term_w);
self.writer.push_styled(&output);
- self.none("\n\n");
+ self.writer.push_str("\n\n");
}
}
@@ -318,7 +330,7 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
self.cmd.get_after_help()
};
if let Some(output) = after_help {
- self.none("\n\n");
+ self.writer.push_str("\n\n");
let mut output = output.clone();
output.replace_newline_var();
output.wrap(self.term_w);
@@ -333,6 +345,9 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
/// including titles of a Parser Object to the wrapped stream.
pub(crate) fn write_all_args(&mut self) {
debug!("HelpTemplate::write_all_args");
+ use std::fmt::Write as _;
+ let header = &self.styles.get_header();
+
let pos = self
.cmd
.get_positionals()
@@ -357,39 +372,52 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
if subcmds {
if !first {
- self.none("\n\n");
+ self.writer.push_str("\n\n");
}
first = false;
let default_help_heading = Str::from("Commands");
- self.header(
- self.cmd
- .get_subcommand_help_heading()
- .unwrap_or(&default_help_heading),
+ let help_heading = self
+ .cmd
+ .get_subcommand_help_heading()
+ .unwrap_or(&default_help_heading);
+ let _ = write!(
+ self.writer,
+ "{}{help_heading}:{}\n",
+ header.render(),
+ header.render_reset()
);
- self.header(":");
- self.none("\n");
self.write_subcommands(self.cmd);
}
if !pos.is_empty() {
if !first {
- self.none("\n\n");
+ self.writer.push_str("\n\n");
}
first = false;
// Write positional args if any
- self.header("Arguments:");
- self.none("\n");
+ let help_heading = "Arguments";
+ let _ = write!(
+ self.writer,
+ "{}{help_heading}:{}\n",
+ header.render(),
+ header.render_reset()
+ );
self.write_args(&pos, "Arguments", positional_sort_key);
}
if !non_pos.is_empty() {
if !first {
- self.none("\n\n");
+ self.writer.push_str("\n\n");
}
first = false;
- self.header("Options:");
- self.none("\n");
+ let help_heading = "Options";
+ let _ = write!(
+ self.writer,
+ "{}{help_heading}:{}\n",
+ header.render(),
+ header.render_reset()
+ );
self.write_args(&non_pos, "Options", option_sort_key);
}
if !custom_headings.is_empty() {
@@ -408,12 +436,15 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
if !args.is_empty() {
if !first {
- self.none("\n\n");
+ self.writer.push_str("\n\n");
}
first = false;
- self.header(heading);
- self.header(":");
- self.none("\n");
+ let _ = write!(
+ self.writer,
+ "{}{heading}:{}\n",
+ header.render(),
+ header.render_reset()
+ );
self.write_args(&args, heading, option_sort_key);
}
}
@@ -451,9 +482,9 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
for (i, (_, arg)) in ord_v.iter().enumerate() {
if i != 0 {
- self.none("\n");
+ self.writer.push_str("\n");
if next_line_help && self.use_long {
- self.none("\n");
+ self.writer.push_str("\n");
}
}
self.write_arg(arg, next_line_help, longest);
@@ -464,10 +495,11 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
fn write_arg(&mut self, arg: &Arg, next_line_help: bool, longest: usize) {
let spec_vals = &self.spec_vals(arg);
- self.none(TAB);
+ self.writer.push_str(TAB);
self.short(arg);
self.long(arg);
- self.writer.push_styled(&arg.stylize_arg_suffix(None));
+ self.writer
+ .push_styled(&arg.stylize_arg_suffix(self.styles, None));
self.align_to_about(arg, next_line_help, longest);
let about = if self.use_long {
@@ -486,22 +518,37 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
/// Writes argument's short command to the wrapped stream.
fn short(&mut self, arg: &Arg) {
debug!("HelpTemplate::short");
+ use std::fmt::Write as _;
+ let literal = &self.styles.get_literal();
if let Some(s) = arg.get_short() {
- self.literal(format!("-{s}"));
+ let _ = write!(
+ self.writer,
+ "{}-{s}{}",
+ literal.render(),
+ literal.render_reset()
+ );
} else if arg.get_long().is_some() {
- self.none(" ");
+ self.writer.push_str(" ");
}
}
/// Writes argument's long command to the wrapped stream.
fn long(&mut self, arg: &Arg) {
debug!("HelpTemplate::long");
+ use std::fmt::Write as _;
+ let literal = &self.styles.get_literal();
+
if let Some(long) = arg.get_long() {
if arg.get_short().is_some() {
- self.none(", ");
+ self.writer.push_str(", ");
}
- self.literal(format!("--{long}"));
+ let _ = write!(
+ self.writer,
+ "{}--{long}{}",
+ literal.render(),
+ literal.render_reset()
+ );
}
}
@@ -513,9 +560,10 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
next_line_help,
longest
);
- if self.use_long || next_line_help {
+ let padding = if self.use_long || next_line_help {
// long help prints messages on the next line so it doesn't need to align text
debug!("HelpTemplate::align_to_about: printing long help so skip alignment");
+ 0
} else if !arg.is_positional() {
let self_len = display_width(&arg.to_string());
// Since we're writing spaces from the tab point we first need to know if we
@@ -533,7 +581,7 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
self_len, spcs
);
- self.spaces(spcs);
+ spcs
} else {
let self_len = display_width(&arg.to_string());
let padding = TAB_WIDTH;
@@ -543,8 +591,10 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
self_len, spcs
);
- self.spaces(spcs);
- }
+ spcs
+ };
+
+ self.write_padding(padding);
}
/// Writes argument's help to the wrapped stream.
@@ -557,13 +607,15 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
longest: usize,
) {
debug!("HelpTemplate::help");
+ use std::fmt::Write as _;
+ let literal = &self.styles.get_literal();
// Is help on next line, if so then indent
if next_line_help {
debug!("HelpTemplate::help: Next Line...{:?}", next_line_help);
- self.none("\n");
- self.none(TAB);
- self.none(NEXT_LINE_INDENT);
+ self.writer.push_str("\n");
+ self.writer.push_str(TAB);
+ self.writer.push_str(NEXT_LINE_INDENT);
}
let spaces = if next_line_help {
@@ -585,9 +637,9 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
} else {
" "
};
- help.none(sep);
+ help.push_str(sep);
}
- help.none(spec_vals);
+ help.push_str(spec_vals);
}
let avail_chars = self.term_w.saturating_sub(spaces);
debug!(
@@ -612,11 +664,6 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
"HelpTemplate::help: Found possible vals...{:?}",
possible_vals
);
- if !help_is_empty {
- self.none("\n\n");
- self.spaces(spaces);
- }
- self.none("Possible values:");
let longest = possible_vals
.iter()
.filter_map(|f| f.get_visible_quoted_name().map(|name| display_width(&name)))
@@ -641,21 +688,29 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
};
let trailing_indent = self.get_spaces(trailing_indent);
+ if !help_is_empty {
+ let _ = write!(self.writer, "\n\n{:spaces$}", "");
+ }
+ self.writer.push_str("Possible values:");
for pv in possible_vals.iter().filter(|pv| !pv.is_hide_set()) {
- self.none("\n");
- self.spaces(spaces);
- self.none("- ");
- self.literal(pv.get_name());
+ let name = pv.get_name();
+ let _ = write!(
+ self.writer,
+ "\n{:spaces$}- {}{name}{}",
+ "",
+ literal.render(),
+ literal.render_reset()
+ );
if let Some(help) = pv.get_help() {
debug!("HelpTemplate::help: Possible Value help");
if possible_value_new_line {
- self.none(":\n");
- self.spaces(trailing_indent.len());
+ let padding = trailing_indent.len();
+ let _ = write!(self.writer, ":\n{:padding$}", "");
} else {
- self.none(": ");
// To align help messages
- self.spaces(longest - display_width(pv.get_name()));
+ let padding = longest - display_width(pv.get_name());
+ let _ = write!(self.writer, ": {:padding$}", "");
}
let avail_chars = if self.term_w > trailing_indent.len() {
@@ -801,24 +856,13 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
spec_vals.join(connector)
}
- fn header<T: Into<String>>(&mut self, msg: T) {
- self.writer.header(msg);
- }
-
- fn literal<T: Into<String>>(&mut self, msg: T) {
- self.writer.literal(msg);
- }
-
- fn none<T: Into<String>>(&mut self, msg: T) {
- self.writer.none(msg);
- }
-
fn get_spaces(&self, n: usize) -> String {
" ".repeat(n)
}
- fn spaces(&mut self, n: usize) {
- self.none(self.get_spaces(n));
+ fn write_padding(&mut self, amount: usize) {
+ use std::fmt::Write as _;
+ let _ = write!(self.writer, "{:amount$}", "");
}
}
@@ -827,6 +871,9 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
/// Writes help for subcommands of a Parser Object to the wrapped stream.
fn write_subcommands(&mut self, cmd: &Command) {
debug!("HelpTemplate::write_subcommands");
+ use std::fmt::Write as _;
+ let literal = &self.styles.get_literal();
+
// The shortest an arg can legally be is 2 (i.e. '-x')
let mut longest = 2;
let mut ord_v = Vec::new();
@@ -835,14 +882,28 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
.filter(|subcommand| should_show_subcommand(subcommand))
{
let mut styled = StyledStr::new();
- styled.literal(subcommand.get_name());
+ let name = subcommand.get_name();
+ let _ = write!(
+ styled,
+ "{}{name}{}",
+ literal.render(),
+ literal.render_reset()
+ );
if let Some(short) = subcommand.get_short_flag() {
- styled.none(", ");
- styled.literal(format!("-{short}"));
+ let _ = write!(
+ styled,
+ ", {}-{short}{}",
+ literal.render(),
+ literal.render_reset()
+ );
}
if let Some(long) = subcommand.get_long_flag() {
- styled.none(", ");
- styled.literal(format!("--{long}"));
+ let _ = write!(
+ styled,
+ ", {}--{long}{}",
+ literal.render(),
+ literal.render_reset()
+ );
}
longest = longest.max(styled.display_width());
ord_v.push((subcommand.get_display_order(), styled, subcommand));
@@ -858,7 +919,7 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
if first {
first = false;
} else {
- self.none("\n");
+ self.writer.push_str("\n");
}
self.write_subcommand(sc_str, sc, next_line_help, longest);
}
@@ -942,12 +1003,12 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
/// Writes subcommand to the wrapped stream.
fn subcmd(&mut self, sc_str: StyledStr, next_line_help: bool, longest: usize) {
- let width = sc_str.display_width();
-
- self.none(TAB);
+ self.writer.push_str(TAB);
self.writer.push_styled(&sc_str);
if !next_line_help {
- self.spaces(longest + TAB_WIDTH - width);
+ let width = sc_str.display_width();
+ let padding = longest + TAB_WIDTH - width;
+ self.write_padding(padding);
}
}
}
diff --git a/vendor/clap_builder/src/output/usage.rs b/vendor/clap_builder/src/output/usage.rs
index c49ca2cb0..dd99c63c7 100644
--- a/vendor/clap_builder/src/output/usage.rs
+++ b/vendor/clap_builder/src/output/usage.rs
@@ -5,6 +5,7 @@
// Internal
use crate::builder::StyledStr;
+use crate::builder::Styles;
use crate::builder::{ArgPredicate, Command};
use crate::parser::ArgMatcher;
use crate::util::ChildGraph;
@@ -15,6 +16,7 @@ static DEFAULT_SUB_VALUE_NAME: &str = "COMMAND";
pub(crate) struct Usage<'cmd> {
cmd: &'cmd Command,
+ styles: &'cmd Styles,
required: Option<&'cmd ChildGraph<Id>>,
}
@@ -22,6 +24,7 @@ impl<'cmd> Usage<'cmd> {
pub(crate) fn new(cmd: &'cmd Command) -> Self {
Usage {
cmd,
+ styles: cmd.get_styles(),
required: None,
}
}
@@ -37,9 +40,14 @@ impl<'cmd> Usage<'cmd> {
debug!("Usage::create_usage_with_title");
let usage = some!(self.create_usage_no_title(used));
+ use std::fmt::Write as _;
let mut styled = StyledStr::new();
- styled.header("Usage:");
- styled.none(" ");
+ let _ = write!(
+ styled,
+ "{}Usage:{} ",
+ self.styles.get_usage().render(),
+ self.styles.get_usage().render_reset()
+ );
styled.push_styled(&usage);
Some(styled)
}
@@ -72,16 +80,33 @@ impl<'cmd> Usage<'cmd> {
// Creates a usage string for display in help messages (i.e. not for errors)
fn create_help_usage(&self, incl_reqs: bool) -> StyledStr {
debug!("Usage::create_help_usage; incl_reqs={:?}", incl_reqs);
+ use std::fmt::Write as _;
+ let literal = &self.styles.get_literal();
+ let placeholder = &self.styles.get_placeholder();
let mut styled = StyledStr::new();
+
let name = self
.cmd
.get_usage_name()
.or_else(|| self.cmd.get_bin_name())
.unwrap_or_else(|| self.cmd.get_name());
- styled.literal(name);
+ if !name.is_empty() {
+ // the trim won't properly remove a leading space due to the formatting
+ let _ = write!(
+ styled,
+ "{}{name}{}",
+ literal.render(),
+ literal.render_reset()
+ );
+ }
if self.needs_options_tag() {
- styled.placeholder(" [OPTIONS]");
+ let _ = write!(
+ styled,
+ "{} [OPTIONS]{}",
+ placeholder.render(),
+ placeholder.render_reset()
+ );
}
self.write_args(&[], !incl_reqs, &mut styled);
@@ -90,32 +115,45 @@ impl<'cmd> Usage<'cmd> {
if self.cmd.has_visible_subcommands() && incl_reqs
|| self.cmd.is_allow_external_subcommands_set()
{
- let placeholder = self
+ 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.none("\n");
- styled.none(" ");
+ let _ = write!(styled, "\n ");
if self.cmd.is_args_conflicts_with_subcommands_set() {
// Short-circuit full usage creation since no args will be relevant
- styled.literal(name);
+ let _ = write!(
+ styled,
+ "{}{name}{}",
+ literal.render(),
+ literal.render_reset()
+ );
} else {
styled.push_styled(&self.create_help_usage(false));
}
- styled.placeholder(" <");
- styled.placeholder(placeholder);
- styled.placeholder(">");
+ let _ = write!(
+ styled,
+ " {}<{value_name}>{}",
+ placeholder.render(),
+ placeholder.render_reset()
+ );
} else if self.cmd.is_subcommand_required_set() {
- styled.placeholder(" <");
- styled.placeholder(placeholder);
- styled.placeholder(">");
+ let _ = write!(
+ styled,
+ " {}<{value_name}>{}",
+ placeholder.render(),
+ placeholder.render_reset()
+ );
} else {
- styled.placeholder(" [");
- styled.placeholder(placeholder);
- styled.placeholder("]");
+ let _ = write!(
+ styled,
+ " {}[{value_name}]{}",
+ placeholder.render(),
+ placeholder.render_reset()
+ );
}
}
styled.trim();
@@ -127,25 +165,36 @@ impl<'cmd> Usage<'cmd> {
// args, and requirements
fn create_smart_usage(&self, used: &[Id]) -> StyledStr {
debug!("Usage::create_smart_usage");
+ use std::fmt::Write;
+ let literal = &self.styles.get_literal();
+ let placeholder = &self.styles.get_placeholder();
let mut styled = StyledStr::new();
- styled.literal(
- self.cmd
- .get_usage_name()
- .or_else(|| self.cmd.get_bin_name())
- .unwrap_or_else(|| self.cmd.get_name()),
+ let bin_name = self
+ .cmd
+ .get_usage_name()
+ .or_else(|| self.cmd.get_bin_name())
+ .unwrap_or_else(|| self.cmd.get_name());
+ let _ = write!(
+ styled,
+ "{}{bin_name}{}",
+ literal.render(),
+ literal.render_reset()
);
self.write_args(used, false, &mut styled);
if self.cmd.is_subcommand_required_set() {
- styled.placeholder(" <");
- styled.placeholder(
- self.cmd
- .get_subcommand_value_name()
- .unwrap_or(DEFAULT_SUB_VALUE_NAME),
+ 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()
);
- styled.placeholder(">");
}
styled
}
@@ -189,13 +238,15 @@ impl<'cmd> Usage<'cmd> {
// Returns the required args in usage string form by fully unrolling all groups
pub(crate) fn write_args(&self, incls: &[Id], force_optional: bool, styled: &mut StyledStr) {
for required in self.get_args(incls, force_optional) {
- styled.none(" ");
+ styled.push_str(" ");
styled.push_styled(&required);
}
}
pub(crate) fn get_args(&self, incls: &[Id], force_optional: bool) -> Vec<StyledStr> {
debug!("Usage::get_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 {
@@ -247,7 +298,7 @@ impl<'cmd> Usage<'cmd> {
continue;
}
- let stylized = arg.stylized(Some(!force_optional));
+ 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 {
@@ -279,7 +330,7 @@ impl<'cmd> Usage<'cmd> {
if pos.is_last_set() {
let styled = required_positionals[index].take().unwrap();
let mut new = StyledStr::new();
- new.literal("-- ");
+ let _ = write!(new, "{}--{} ", literal.render(), literal.render_reset());
new.push_styled(&styled);
required_positionals[index] = Some(new);
}
@@ -287,11 +338,11 @@ impl<'cmd> Usage<'cmd> {
let mut styled;
if pos.is_last_set() {
styled = StyledStr::new();
- styled.literal("[-- ");
- styled.push_styled(&pos.stylized(Some(true)));
- styled.literal("]");
+ 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(Some(false));
+ styled = pos.stylized(self.styles, Some(false));
}
required_positionals[index] = Some(styled);
}
@@ -411,7 +462,7 @@ impl<'cmd> Usage<'cmd> {
continue;
}
- let stylized = arg.stylized(Some(true));
+ 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;
diff --git a/vendor/clap_builder/src/parser/arg_matcher.rs b/vendor/clap_builder/src/parser/arg_matcher.rs
index d584689cd..124d46f5f 100644
--- a/vendor/clap_builder/src/parser/arg_matcher.rs
+++ b/vendor/clap_builder/src/parser/arg_matcher.rs
@@ -5,10 +5,10 @@ use std::ops::Deref;
// Internal
use crate::builder::{Arg, ArgPredicate, Command};
-use crate::parser::AnyValue;
use crate::parser::Identifier;
use crate::parser::PendingArg;
use crate::parser::{ArgMatches, MatchedArg, SubCommand, ValueSource};
+use crate::util::AnyValue;
use crate::util::FlatMap;
use crate::util::Id;
use crate::INTERNAL_ERROR_MSG;
@@ -130,7 +130,9 @@ impl ArgMatcher {
}
pub(crate) fn check_explicit(&self, arg: &Id, predicate: &ArgPredicate) -> bool {
- self.get(arg).map_or(false, |a| a.check_explicit(predicate))
+ self.get(arg)
+ .map(|a| a.check_explicit(predicate))
+ .unwrap_or_default()
}
pub(crate) fn start_custom_arg(&mut self, arg: &Arg, source: ValueSource) {
diff --git a/vendor/clap_builder/src/parser/error.rs b/vendor/clap_builder/src/parser/error.rs
index 66b2bc79e..77b0bb0fc 100644
--- a/vendor/clap_builder/src/parser/error.rs
+++ b/vendor/clap_builder/src/parser/error.rs
@@ -1,3 +1,5 @@
+use crate::util::AnyValueId;
+
/// Violation of [`ArgMatches`][crate::ArgMatches] assumptions
#[derive(Clone, Debug)]
#[allow(missing_copy_implementations)] // We might add non-Copy types in the future
@@ -7,9 +9,9 @@ pub enum MatchesError {
#[non_exhaustive]
Downcast {
/// Type for value stored in [`ArgMatches`][crate::ArgMatches]
- actual: super::AnyValueId,
+ actual: AnyValueId,
/// The target type to downcast to
- expected: super::AnyValueId,
+ expected: AnyValueId,
},
/// Argument not defined in [`Command`][crate::Command]
#[non_exhaustive]
diff --git a/vendor/clap_builder/src/parser/matches/arg_matches.rs b/vendor/clap_builder/src/parser/matches/arg_matches.rs
index 306ce9ed2..da8a34783 100644
--- a/vendor/clap_builder/src/parser/matches/arg_matches.rs
+++ b/vendor/clap_builder/src/parser/matches/arg_matches.rs
@@ -8,11 +8,11 @@ use std::slice::Iter;
// Internal
#[cfg(debug_assertions)]
use crate::builder::Str;
-use crate::parser::AnyValue;
-use crate::parser::AnyValueId;
use crate::parser::MatchedArg;
use crate::parser::MatchesError;
use crate::parser::ValueSource;
+use crate::util::AnyValue;
+use crate::util::AnyValueId;
use crate::util::FlatMap;
use crate::util::Id;
use crate::INTERNAL_ERROR_MSG;
diff --git a/vendor/clap_builder/src/parser/matches/matched_arg.rs b/vendor/clap_builder/src/parser/matches/matched_arg.rs
index 901990cfb..24df8b160 100644
--- a/vendor/clap_builder/src/parser/matches/matched_arg.rs
+++ b/vendor/clap_builder/src/parser/matches/matched_arg.rs
@@ -6,10 +6,10 @@ use std::{
};
use crate::builder::ArgPredicate;
-use crate::parser::AnyValue;
-use crate::parser::AnyValueId;
use crate::parser::ValueSource;
use crate::util::eq_ignore_case;
+use crate::util::AnyValue;
+use crate::util::AnyValueId;
use crate::INTERNAL_ERROR_MSG;
#[derive(Debug, Clone)]
diff --git a/vendor/clap_builder/src/parser/matches/mod.rs b/vendor/clap_builder/src/parser/matches/mod.rs
index 0e3474fb3..eb865853c 100644
--- a/vendor/clap_builder/src/parser/matches/mod.rs
+++ b/vendor/clap_builder/src/parser/matches/mod.rs
@@ -1,9 +1,7 @@
-mod any_value;
mod arg_matches;
mod matched_arg;
mod value_source;
-pub use any_value::AnyValueId;
pub use arg_matches::IdsRef;
pub use arg_matches::RawValues;
pub use arg_matches::Values;
@@ -11,6 +9,5 @@ pub use arg_matches::ValuesRef;
pub use arg_matches::{ArgMatches, Indices};
pub use value_source::ValueSource;
-pub(crate) use any_value::AnyValue;
pub(crate) use arg_matches::SubCommand;
pub(crate) use matched_arg::MatchedArg;
diff --git a/vendor/clap_builder/src/parser/mod.rs b/vendor/clap_builder/src/parser/mod.rs
index c99e74f95..3e73544d5 100644
--- a/vendor/clap_builder/src/parser/mod.rs
+++ b/vendor/clap_builder/src/parser/mod.rs
@@ -10,8 +10,6 @@ mod validator;
pub(crate) mod features;
pub(crate) use self::arg_matcher::ArgMatcher;
-pub(crate) use self::matches::AnyValue;
-pub(crate) use self::matches::AnyValueId;
pub(crate) use self::matches::{MatchedArg, SubCommand};
pub(crate) use self::parser::Identifier;
pub(crate) use self::parser::PendingArg;
diff --git a/vendor/clap_builder/src/parser/parser.rs b/vendor/clap_builder/src/parser/parser.rs
index c29100485..723e1cd69 100644
--- a/vendor/clap_builder/src/parser/parser.rs
+++ b/vendor/clap_builder/src/parser/parser.rs
@@ -13,9 +13,9 @@ use crate::error::Result as ClapResult;
use crate::mkeymap::KeyType;
use crate::output::Usage;
use crate::parser::features::suggestions;
-use crate::parser::AnyValue;
use crate::parser::{ArgMatcher, SubCommand};
use crate::parser::{Validator, ValueSource};
+use crate::util::AnyValue;
use crate::util::Id;
use crate::ArgAction;
use crate::INTERNAL_ERROR_MSG;
@@ -305,7 +305,8 @@ impl<'cmd> Parser<'cmd> {
.cmd
.get_positionals()
.last()
- .map_or(false, |p_name| !p_name.is_last_set());
+ .map(|p_name| !p_name.is_last_set())
+ .unwrap_or_default();
let missing_pos = self.cmd.is_allow_missing_positional_set()
&& is_second_to_last
@@ -779,9 +780,10 @@ impl<'cmd> Parser<'cmd> {
matcher.check_explicit(arg_id, &crate::builder::ArgPredicate::IsPresent)
})
.filter(|&n| {
- self.cmd.find(n).map_or(true, |a| {
- !(a.is_hide_set() || required.contains(a.get_id()))
- })
+ self.cmd
+ .find(n)
+ .map(|a| !(a.is_hide_set() || required.contains(a.get_id())))
+ .unwrap_or(true)
})
.cloned()
.collect();
@@ -810,9 +812,8 @@ impl<'cmd> Parser<'cmd> {
.cmd
.get_keymap()
.get(&pos_counter)
- .map_or(false, |arg| {
- arg.is_allow_hyphen_values_set() && !arg.is_last_set()
- })
+ .map(|arg| arg.is_allow_hyphen_values_set() && !arg.is_last_set())
+ .unwrap_or_default()
{
debug!(
"Parser::parse_long_args: positional at {} allows hyphens",
@@ -847,7 +848,8 @@ impl<'cmd> Parser<'cmd> {
.cmd
.get_keymap()
.get(&pos_counter)
- .map_or(false, |arg| arg.is_allow_negative_numbers_set())
+ .map(|arg| arg.is_allow_negative_numbers_set())
+ .unwrap_or_default()
&& short_arg.is_number()
{
debug!("Parser::parse_short_arg: negative number");
@@ -856,9 +858,8 @@ impl<'cmd> Parser<'cmd> {
.cmd
.get_keymap()
.get(&pos_counter)
- .map_or(false, |arg| {
- arg.is_allow_hyphen_values_set() && !arg.is_last_set()
- })
+ .map(|arg| arg.is_allow_hyphen_values_set() && !arg.is_last_set())
+ .unwrap_or_default()
&& short_arg
.clone()
.any(|c| !c.map(|c| self.cmd.contains_short(c)).unwrap_or_default())
@@ -1536,7 +1537,7 @@ impl<'cmd> Parser<'cmd> {
.filter(|arg_id| {
matcher.check_explicit(arg_id, &crate::builder::ArgPredicate::IsPresent)
})
- .filter(|n| self.cmd.find(n).map_or(true, |a| !a.is_hide_set()))
+ .filter(|n| self.cmd.find(n).map(|a| !a.is_hide_set()).unwrap_or(true))
.cloned()
.collect();
diff --git a/vendor/clap_builder/src/parser/validator.rs b/vendor/clap_builder/src/parser/validator.rs
index 49d28a34f..5c3d34643 100644
--- a/vendor/clap_builder/src/parser/validator.rs
+++ b/vendor/clap_builder/src/parser/validator.rs
@@ -199,7 +199,10 @@ impl<'cmd> Validator<'cmd> {
.map(|(n, _)| n)
.filter(|n| {
// Filter out the args we don't want to specify.
- self.cmd.find(n).map_or(false, |a| !a.is_hide_set())
+ self.cmd
+ .find(n)
+ .map(|a| !a.is_hide_set())
+ .unwrap_or_default()
})
.filter(|key| !conflicting_keys.contains(key))
.cloned()
@@ -445,7 +448,10 @@ impl<'cmd> Validator<'cmd> {
.map(|(n, _)| n)
.filter(|n| {
// Filter out the args we don't want to specify.
- self.cmd.find(n).map_or(false, |a| !a.is_hide_set())
+ self.cmd
+ .find(n)
+ .map(|a| !a.is_hide_set())
+ .unwrap_or_default()
})
.cloned()
.chain(raw_req_args)
diff --git a/vendor/clap_builder/src/parser/matches/any_value.rs b/vendor/clap_builder/src/util/any_value.rs
index dc7a3e953..dc7a3e953 100644
--- a/vendor/clap_builder/src/parser/matches/any_value.rs
+++ b/vendor/clap_builder/src/util/any_value.rs
diff --git a/vendor/clap_builder/src/util/mod.rs b/vendor/clap_builder/src/util/mod.rs
index e6a8f70ed..a92aef8c3 100644
--- a/vendor/clap_builder/src/util/mod.rs
+++ b/vendor/clap_builder/src/util/mod.rs
@@ -1,5 +1,6 @@
#![allow(clippy::single_component_path_imports)]
+mod any_value;
pub(crate) mod flat_map;
pub(crate) mod flat_set;
mod graph;
@@ -8,6 +9,8 @@ mod str_to_bool;
pub use self::id::Id;
+pub(crate) use self::any_value::AnyValue;
+pub(crate) use self::any_value::AnyValueId;
pub(crate) use self::flat_map::Entry;
pub(crate) use self::flat_map::FlatMap;
pub(crate) use self::flat_set::FlatSet;