From 27431a43a1713abab32afb6d85486d547eaf65fd Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 29 Jun 2023 20:24:34 -0500 Subject: [PATCH] refactor(builder): Remove bitflags dependency This saved 1.3 KiB When color support is enabled, this likely won't save on build times *until* `is-terminal` is removed. At that point, `bitflags` will no longer be in our dependency tree. I did not (yet) reproduce the `Debug` impl. --- Cargo.lock | 1 - clap_builder/Cargo.toml | 1 - clap_builder/src/builder/app_settings.rs | 148 +++++------------------ clap_builder/src/builder/arg.rs | 14 +-- clap_builder/src/builder/arg_settings.rs | 115 +++++------------- clap_builder/src/builder/command.rs | 41 +++---- clap_builder/src/macros.rs | 93 -------------- 7 files changed, 78 insertions(+), 335 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 40f5ea9f7c9..792e615d724 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -523,7 +523,6 @@ dependencies = [ "anstream", "anstyle", "backtrace", - "bitflags 2.3.3", "clap_lex 0.5.0", "color-print", "humantime", diff --git a/clap_builder/Cargo.toml b/clap_builder/Cargo.toml index 1bbe4393664..19f3451c81a 100644 --- a/clap_builder/Cargo.toml +++ b/clap_builder/Cargo.toml @@ -59,7 +59,6 @@ bench = false [dependencies] clap_lex = { path = "../clap_lex", version = "0.5.0" } -bitflags = "2.3.3" unicase = { version = "2.6.0", optional = true } strsim = { version = "0.10.0", optional = true } anstream = { version = "0.3.0", optional = true } diff --git a/clap_builder/src/builder/app_settings.rs b/clap_builder/src/builder/app_settings.rs index a531f57e1ce..4fce4b4a2ee 100644 --- a/clap_builder/src/builder/app_settings.rs +++ b/clap_builder/src/builder/app_settings.rs @@ -1,21 +1,35 @@ -// Std -use std::ops::BitOr; - #[allow(unused)] use crate::Arg; #[allow(unused)] use crate::Command; -// Third party -use bitflags::bitflags; +#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)] +pub(crate) struct AppFlags(u32); + +impl AppFlags { + pub(crate) fn set(&mut self, setting: AppSettings) { + self.0 |= setting.bit(); + } + + pub(crate) fn unset(&mut self, setting: AppSettings) { + self.0 &= !setting.bit(); + } + + pub(crate) fn is_set(&self, setting: AppSettings) -> bool { + self.0 & setting.bit() != 0 + } + + pub(crate) fn insert(&mut self, other: Self) { + self.0 |= other.0; + } +} -#[doc(hidden)] -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub(crate) struct AppFlags(Flags); +impl std::ops::BitOr for AppFlags { + type Output = Self; -impl Default for AppFlags { - fn default() -> Self { - AppFlags(Flags::COLOR_AUTO) + fn bitor(mut self, rhs: Self) -> Self::Output { + self.insert(rhs); + self } } @@ -26,7 +40,7 @@ impl Default for AppFlags { /// /// [`Command`]: crate::Command #[derive(Debug, PartialEq, Copy, Clone)] -#[non_exhaustive] +#[repr(u8)] pub(crate) enum AppSettings { IgnoreErrors, AllowHyphenValues, @@ -62,112 +76,8 @@ pub(crate) enum AppSettings { BinNameBuilt, } -bitflags! { - #[derive(Debug, Copy, Clone, PartialEq, Eq)] - struct Flags: u64 { - const SC_NEGATE_REQS = 1; - const SC_REQUIRED = 1 << 1; - const ARG_REQUIRED_ELSE_HELP = 1 << 2; - const PROPAGATE_VERSION = 1 << 3; - const DISABLE_VERSION_FOR_SC = 1 << 4; - const WAIT_ON_ERROR = 1 << 6; - const DISABLE_VERSION_FLAG = 1 << 10; - const HIDDEN = 1 << 11; - const TRAILING_VARARG = 1 << 12; - const NO_BIN_NAME = 1 << 13; - const ALLOW_UNK_SC = 1 << 14; - const LEADING_HYPHEN = 1 << 16; - const NO_POS_VALUES = 1 << 17; - const NEXT_LINE_HELP = 1 << 18; - const DISABLE_COLORED_HELP = 1 << 20; - const COLOR_ALWAYS = 1 << 21; - const COLOR_AUTO = 1 << 22; - const COLOR_NEVER = 1 << 23; - const DONT_DELIM_TRAIL = 1 << 24; - const ALLOW_NEG_NUMS = 1 << 25; - const DISABLE_HELP_SC = 1 << 27; - const ARGS_NEGATE_SCS = 1 << 29; - const PROPAGATE_VALS_DOWN = 1 << 30; - const ALLOW_MISSING_POS = 1 << 31; - const TRAILING_VALUES = 1 << 32; - const BUILT = 1 << 33; - const BIN_NAME_BUILT = 1 << 34; - const VALID_ARG_FOUND = 1 << 35; - const INFER_SUBCOMMANDS = 1 << 36; - const CONTAINS_LAST = 1 << 37; - const ARGS_OVERRIDE_SELF = 1 << 38; - const HELP_REQUIRED = 1 << 39; - const SUBCOMMAND_PRECEDENCE_OVER_ARG = 1 << 40; - const DISABLE_HELP_FLAG = 1 << 41; - const INFER_LONG_ARGS = 1 << 43; - const IGNORE_ERRORS = 1 << 44; - const MULTICALL = 1 << 45; - const EXPAND_HELP_SUBCOMMAND_TREES = 1 << 46; - const NO_OP = 0; +impl AppSettings { + fn bit(self) -> u32 { + 1 << (self as u8) } } - -impl_settings! { AppSettings, AppFlags, - ArgRequiredElseHelp - => Flags::ARG_REQUIRED_ELSE_HELP, - SubcommandPrecedenceOverArg - => Flags::SUBCOMMAND_PRECEDENCE_OVER_ARG, - ArgsNegateSubcommands - => Flags::ARGS_NEGATE_SCS, - AllowExternalSubcommands - => Flags::ALLOW_UNK_SC, - AllowHyphenValues - => Flags::LEADING_HYPHEN, - AllowNegativeNumbers - => Flags::ALLOW_NEG_NUMS, - AllowMissingPositional - => Flags::ALLOW_MISSING_POS, - ColorAlways - => Flags::COLOR_ALWAYS, - ColorAuto - => Flags::COLOR_AUTO, - ColorNever - => Flags::COLOR_NEVER, - DontDelimitTrailingValues - => Flags::DONT_DELIM_TRAIL, - DisableColoredHelp - => Flags::DISABLE_COLORED_HELP, - DisableHelpSubcommand - => Flags::DISABLE_HELP_SC, - DisableHelpFlag - => Flags::DISABLE_HELP_FLAG, - DisableVersionFlag - => Flags::DISABLE_VERSION_FLAG, - PropagateVersion - => Flags::PROPAGATE_VERSION, - HidePossibleValues - => Flags::NO_POS_VALUES, - HelpExpected - => Flags::HELP_REQUIRED, - Hidden - => Flags::HIDDEN, - Multicall - => Flags::MULTICALL, - NoBinaryName - => Flags::NO_BIN_NAME, - SubcommandsNegateReqs - => Flags::SC_NEGATE_REQS, - SubcommandRequired - => Flags::SC_REQUIRED, - TrailingVarArg - => Flags::TRAILING_VARARG, - NextLineHelp - => Flags::NEXT_LINE_HELP, - IgnoreErrors - => Flags::IGNORE_ERRORS, - Built - => Flags::BUILT, - BinNameBuilt - => Flags::BIN_NAME_BUILT, - InferSubcommands - => Flags::INFER_SUBCOMMANDS, - AllArgsOverrideSelf - => Flags::ARGS_OVERRIDE_SELF, - InferLongArgs - => Flags::INFER_LONG_ARGS -} diff --git a/clap_builder/src/builder/arg.rs b/clap_builder/src/builder/arg.rs index 65d7cc956e7..5bfea9ad469 100644 --- a/clap_builder/src/builder/arg.rs +++ b/clap_builder/src/builder/arg.rs @@ -858,21 +858,15 @@ impl Arg { #[inline] #[must_use] - pub(crate) fn setting(mut self, setting: F) -> Self - where - F: Into, - { - self.settings.insert(setting.into()); + pub(crate) fn setting(mut self, setting: ArgSettings) -> Self { + self.settings.set(setting); self } #[inline] #[must_use] - pub(crate) fn unset_setting(mut self, setting: F) -> Self - where - F: Into, - { - self.settings.remove(setting.into()); + pub(crate) fn unset_setting(mut self, setting: ArgSettings) -> Self { + self.settings.unset(setting); self } } diff --git a/clap_builder/src/builder/arg_settings.rs b/clap_builder/src/builder/arg_settings.rs index 6dd4d6c8e73..fd47504047f 100644 --- a/clap_builder/src/builder/arg_settings.rs +++ b/clap_builder/src/builder/arg_settings.rs @@ -1,18 +1,33 @@ -// Std -use std::ops::BitOr; - -// Third party -use bitflags::bitflags; - #[allow(unused)] use crate::Arg; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) struct ArgFlags(Flags); +#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)] +pub(crate) struct ArgFlags(u32); + +impl ArgFlags { + pub(crate) fn set(&mut self, setting: ArgSettings) { + self.0 |= setting.bit(); + } + + pub(crate) fn unset(&mut self, setting: ArgSettings) { + self.0 &= !setting.bit(); + } + + pub(crate) fn is_set(&self, setting: ArgSettings) -> bool { + self.0 & setting.bit() != 0 + } -impl Default for ArgFlags { - fn default() -> Self { - Self::empty() + pub(crate) fn insert(&mut self, other: Self) { + self.0 |= other.0; + } +} + +impl std::ops::BitOr for ArgFlags { + type Output = Self; + + fn bitor(mut self, rhs: Self) -> Self::Output { + self.insert(rhs); + self } } @@ -25,7 +40,7 @@ impl Default for ArgFlags { /// [`Arg::unset_setting`]: crate::Arg::unset_setting() /// [`Arg::is_set`]: crate::Arg::is_set() #[derive(Debug, PartialEq, Copy, Clone)] -#[non_exhaustive] +#[repr(u8)] pub(crate) enum ArgSettings { Required, Global, @@ -48,55 +63,12 @@ pub(crate) enum ArgSettings { Exclusive, } -bitflags! { - #[derive(Debug, Copy, Clone, PartialEq, Eq)] - struct Flags: u32 { - const REQUIRED = 1; - const GLOBAL = 1 << 3; - const HIDDEN = 1 << 4; - const TRAILING_VARARG = 1 << 5; - const ALLOW_NEG_NUMS = 1 << 6; - const NEXT_LINE_HELP = 1 << 7; - const DELIM_NOT_SET = 1 << 10; - const HIDE_POS_VALS = 1 << 11; - const ALLOW_TAC_VALS = 1 << 12; - const REQUIRE_EQUALS = 1 << 13; - const LAST = 1 << 14; - const HIDE_DEFAULT_VAL = 1 << 15; - const CASE_INSENSITIVE = 1 << 16; - #[cfg(feature = "env")] - const HIDE_ENV_VALS = 1 << 17; - const HIDDEN_SHORT_H = 1 << 18; - const HIDDEN_LONG_H = 1 << 19; - #[cfg(feature = "env")] - const HIDE_ENV = 1 << 21; - const EXCLUSIVE = 1 << 23; - const NO_OP = 0; +impl ArgSettings { + fn bit(self) -> u32 { + 1 << (self as u8) } } -impl_settings! { ArgSettings, ArgFlags, - Required => Flags::REQUIRED, - Global => Flags::GLOBAL, - Hidden => Flags::HIDDEN, - NextLineHelp => Flags::NEXT_LINE_HELP, - HidePossibleValues => Flags::HIDE_POS_VALS, - AllowHyphenValues => Flags::ALLOW_TAC_VALS, - AllowNegativeNumbers => Flags::ALLOW_NEG_NUMS, - RequireEquals => Flags::REQUIRE_EQUALS, - Last => Flags::LAST, - TrailingVarArg => Flags::TRAILING_VARARG, - IgnoreCase => Flags::CASE_INSENSITIVE, - #[cfg(feature = "env")] - HideEnv => Flags::HIDE_ENV, - #[cfg(feature = "env")] - HideEnvValues => Flags::HIDE_ENV_VALS, - HideDefaultValue => Flags::HIDE_DEFAULT_VAL, - HiddenShortHelp => Flags::HIDDEN_SHORT_H, - HiddenLongHelp => Flags::HIDDEN_LONG_H, - Exclusive => Flags::EXCLUSIVE -} - #[cfg(test)] mod test { use super::*; @@ -116,31 +88,4 @@ mod test { let m = m.unset_setting(ArgSettings::Required); assert!(!m.is_required_set(), "{m:#?}"); } - - #[test] - fn setting_bitor() { - let m = Arg::new("setting_bitor") - .setting(ArgSettings::Required | ArgSettings::Hidden | ArgSettings::Last); - - assert!(m.is_required_set()); - assert!(m.is_hide_set()); - assert!(m.is_last_set()); - } - - #[test] - fn unset_setting_bitor() { - let m = Arg::new("unset_setting_bitor") - .setting(ArgSettings::Required) - .setting(ArgSettings::Hidden) - .setting(ArgSettings::Last); - - assert!(m.is_required_set()); - assert!(m.is_hide_set()); - assert!(m.is_last_set()); - - let m = m.unset_setting(ArgSettings::Required | ArgSettings::Hidden | ArgSettings::Last); - assert!(!m.is_required_set(), "{m:#?}"); - assert!(!m.is_hide_set(), "{m:#?}"); - assert!(!m.is_last_set(), "{m:#?}"); - } } diff --git a/clap_builder/src/builder/command.rs b/clap_builder/src/builder/command.rs index 71ea73c0e3b..2c5eb198944 100644 --- a/clap_builder/src/builder/command.rs +++ b/clap_builder/src/builder/command.rs @@ -1907,21 +1907,15 @@ impl Command { #[inline] #[must_use] - pub(crate) fn setting(mut self, setting: F) -> Self - where - F: Into, - { - self.settings.insert(setting.into()); + pub(crate) fn setting(mut self, setting: AppSettings) -> Self { + self.settings.set(setting); self } #[inline] #[must_use] - pub(crate) fn unset_setting(mut self, setting: F) -> Self - where - F: Into, - { - self.settings.remove(setting.into()); + pub(crate) fn unset_setting(mut self, setting: AppSettings) -> Self { + self.settings.unset(setting); self } @@ -3852,26 +3846,22 @@ impl Command { self.settings = self.settings | self.g_settings; if self.is_multicall_set() { - self.settings.insert(AppSettings::SubcommandRequired.into()); - self.settings.insert(AppSettings::DisableHelpFlag.into()); - self.settings.insert(AppSettings::DisableVersionFlag.into()); + self.settings.set(AppSettings::SubcommandRequired); + self.settings.set(AppSettings::DisableHelpFlag); + self.settings.set(AppSettings::DisableVersionFlag); } if !cfg!(feature = "help") && self.get_override_help().is_none() { - self.settings.insert(AppSettings::DisableHelpFlag.into()); - self.settings - .insert(AppSettings::DisableHelpSubcommand.into()); + self.settings.set(AppSettings::DisableHelpFlag); + self.settings.set(AppSettings::DisableHelpSubcommand); } if self.is_set(AppSettings::ArgsNegateSubcommands) { - self.settings - .insert(AppSettings::SubcommandsNegateReqs.into()); + self.settings.set(AppSettings::SubcommandsNegateReqs); } if self.external_value_parser.is_some() { - self.settings - .insert(AppSettings::AllowExternalSubcommands.into()); + self.settings.set(AppSettings::AllowExternalSubcommands); } if !self.has_subcommands() { - self.settings - .insert(AppSettings::DisableHelpSubcommand.into()); + self.settings.set(AppSettings::DisableHelpSubcommand); } self._propagate(); @@ -3924,14 +3914,13 @@ impl Command { let is_allow_negative_numbers_set = self.is_allow_negative_numbers_set(); for arg in self.args.args_mut() { if is_allow_hyphen_values_set && arg.is_takes_value_set() { - arg.settings.insert(ArgSettings::AllowHyphenValues.into()); + arg.settings.set(ArgSettings::AllowHyphenValues); } if is_allow_negative_numbers_set && arg.is_takes_value_set() { - arg.settings - .insert(ArgSettings::AllowNegativeNumbers.into()); + arg.settings.set(ArgSettings::AllowNegativeNumbers); } if is_trailing_var_arg_set && arg.get_index() == Some(highest_idx) { - arg.settings.insert(ArgSettings::TrailingVarArg.into()); + arg.settings.set(ArgSettings::TrailingVarArg); } } } diff --git a/clap_builder/src/macros.rs b/clap_builder/src/macros.rs index 713c083891d..945cdaaabaf 100644 --- a/clap_builder/src/macros.rs +++ b/clap_builder/src/macros.rs @@ -531,99 +531,6 @@ macro_rules! arg { }}; } -macro_rules! impl_settings { - ($settings:ident, $flags:ident, - $( - $(#[$inner:ident $($args:tt)*])* - $setting:ident => $flag:path - ),+ - ) => { - impl $flags { - #[allow(dead_code)] - pub(crate) fn empty() -> Self { - $flags(Flags::empty()) - } - - #[allow(dead_code)] - pub(crate) fn insert(&mut self, rhs: Self) { - self.0.insert(rhs.0); - } - - #[allow(dead_code)] - pub(crate) fn remove(&mut self, rhs: Self) { - self.0.remove(rhs.0); - } - - #[allow(dead_code)] - pub(crate) fn set(&mut self, s: $settings) { - match s { - $( - $(#[$inner $($args)*])* - $settings::$setting => self.0.insert($flag), - )* - } - } - - #[allow(dead_code)] - pub(crate) fn unset(&mut self, s: $settings) { - match s { - $( - $(#[$inner $($args)*])* - $settings::$setting => self.0.remove($flag), - )* - } - } - - #[allow(dead_code)] - pub(crate) fn is_set(&self, s: $settings) -> bool { - match s { - $( - $(#[$inner $($args)*])* - $settings::$setting => self.0.contains($flag), - )* - } - } - } - - impl BitOr for $flags { - type Output = Self; - - fn bitor(mut self, rhs: Self) -> Self::Output { - self.0.insert(rhs.0); - self - } - } - - impl From<$settings> for $flags { - fn from(setting: $settings) -> Self { - let mut flags = $flags::empty(); - flags.set(setting); - flags - } - } - - impl BitOr<$settings> for $flags { - type Output = Self; - - fn bitor(mut self, rhs: $settings) -> Self::Output { - self.set(rhs); - self - } - } - - impl BitOr for $settings { - type Output = $flags; - - fn bitor(self, rhs: Self) -> Self::Output { - let mut flags = $flags::empty(); - flags.set(self); - flags.set(rhs); - flags - } - } - } -} - #[cfg(feature = "debug")] macro_rules! debug { ($($arg:tt)*) => ({