Merge pull request #4991 from epage/bit

refactor(builder): Remove bitflags dependency
This commit is contained in:
Ed Page 2023-06-29 20:44:29 -05:00 committed by GitHub
commit 1938cb2219
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 78 additions and 335 deletions

1
Cargo.lock generated
View file

@ -523,7 +523,6 @@ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
"backtrace", "backtrace",
"bitflags 2.3.3",
"clap_lex 0.5.0", "clap_lex 0.5.0",
"color-print", "color-print",
"humantime", "humantime",

View file

@ -59,7 +59,6 @@ bench = false
[dependencies] [dependencies]
clap_lex = { path = "../clap_lex", version = "0.5.0" } clap_lex = { path = "../clap_lex", version = "0.5.0" }
bitflags = "2.3.3"
unicase = { version = "2.6.0", optional = true } unicase = { version = "2.6.0", optional = true }
strsim = { version = "0.10.0", optional = true } strsim = { version = "0.10.0", optional = true }
anstream = { version = "0.3.0", optional = true } anstream = { version = "0.3.0", optional = true }

View file

@ -1,21 +1,35 @@
// Std
use std::ops::BitOr;
#[allow(unused)] #[allow(unused)]
use crate::Arg; use crate::Arg;
#[allow(unused)] #[allow(unused)]
use crate::Command; use crate::Command;
// Third party #[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
use bitflags::bitflags; pub(crate) struct AppFlags(u32);
#[doc(hidden)] impl AppFlags {
#[derive(Debug, Copy, Clone, PartialEq, Eq)] pub(crate) fn set(&mut self, setting: AppSettings) {
pub(crate) struct AppFlags(Flags); self.0 |= setting.bit();
}
impl Default for AppFlags { pub(crate) fn unset(&mut self, setting: AppSettings) {
fn default() -> Self { self.0 &= !setting.bit();
AppFlags(Flags::COLOR_AUTO) }
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;
}
}
impl std::ops::BitOr for AppFlags {
type Output = Self;
fn bitor(mut self, rhs: Self) -> Self::Output {
self.insert(rhs);
self
} }
} }
@ -26,7 +40,7 @@ impl Default for AppFlags {
/// ///
/// [`Command`]: crate::Command /// [`Command`]: crate::Command
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Copy, Clone)]
#[non_exhaustive] #[repr(u8)]
pub(crate) enum AppSettings { pub(crate) enum AppSettings {
IgnoreErrors, IgnoreErrors,
AllowHyphenValues, AllowHyphenValues,
@ -62,112 +76,8 @@ pub(crate) enum AppSettings {
BinNameBuilt, BinNameBuilt,
} }
bitflags! { impl AppSettings {
#[derive(Debug, Copy, Clone, PartialEq, Eq)] fn bit(self) -> u32 {
struct Flags: u64 { 1 << (self as u8)
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_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
}

View file

@ -858,21 +858,15 @@ impl Arg {
#[inline] #[inline]
#[must_use] #[must_use]
pub(crate) fn setting<F>(mut self, setting: F) -> Self pub(crate) fn setting(mut self, setting: ArgSettings) -> Self {
where self.settings.set(setting);
F: Into<ArgFlags>,
{
self.settings.insert(setting.into());
self self
} }
#[inline] #[inline]
#[must_use] #[must_use]
pub(crate) fn unset_setting<F>(mut self, setting: F) -> Self pub(crate) fn unset_setting(mut self, setting: ArgSettings) -> Self {
where self.settings.unset(setting);
F: Into<ArgFlags>,
{
self.settings.remove(setting.into());
self self
} }
} }

View file

@ -1,18 +1,33 @@
// Std
use std::ops::BitOr;
// Third party
use bitflags::bitflags;
#[allow(unused)] #[allow(unused)]
use crate::Arg; use crate::Arg;
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) struct ArgFlags(Flags); pub(crate) struct ArgFlags(u32);
impl Default for ArgFlags { impl ArgFlags {
fn default() -> Self { pub(crate) fn set(&mut self, setting: ArgSettings) {
Self::empty() 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
}
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::unset_setting`]: crate::Arg::unset_setting()
/// [`Arg::is_set`]: crate::Arg::is_set() /// [`Arg::is_set`]: crate::Arg::is_set()
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Copy, Clone)]
#[non_exhaustive] #[repr(u8)]
pub(crate) enum ArgSettings { pub(crate) enum ArgSettings {
Required, Required,
Global, Global,
@ -48,55 +63,12 @@ pub(crate) enum ArgSettings {
Exclusive, Exclusive,
} }
bitflags! { impl ArgSettings {
#[derive(Debug, Copy, Clone, PartialEq, Eq)] fn bit(self) -> u32 {
struct Flags: u32 { 1 << (self as u8)
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_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)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
@ -116,31 +88,4 @@ mod test {
let m = m.unset_setting(ArgSettings::Required); let m = m.unset_setting(ArgSettings::Required);
assert!(!m.is_required_set(), "{m:#?}"); 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:#?}");
}
} }

View file

@ -1907,21 +1907,15 @@ impl Command {
#[inline] #[inline]
#[must_use] #[must_use]
pub(crate) fn setting<F>(mut self, setting: F) -> Self pub(crate) fn setting(mut self, setting: AppSettings) -> Self {
where self.settings.set(setting);
F: Into<AppFlags>,
{
self.settings.insert(setting.into());
self self
} }
#[inline] #[inline]
#[must_use] #[must_use]
pub(crate) fn unset_setting<F>(mut self, setting: F) -> Self pub(crate) fn unset_setting(mut self, setting: AppSettings) -> Self {
where self.settings.unset(setting);
F: Into<AppFlags>,
{
self.settings.remove(setting.into());
self self
} }
@ -3852,26 +3846,22 @@ impl Command {
self.settings = self.settings | self.g_settings; self.settings = self.settings | self.g_settings;
if self.is_multicall_set() { if self.is_multicall_set() {
self.settings.insert(AppSettings::SubcommandRequired.into()); self.settings.set(AppSettings::SubcommandRequired);
self.settings.insert(AppSettings::DisableHelpFlag.into()); self.settings.set(AppSettings::DisableHelpFlag);
self.settings.insert(AppSettings::DisableVersionFlag.into()); self.settings.set(AppSettings::DisableVersionFlag);
} }
if !cfg!(feature = "help") && self.get_override_help().is_none() { if !cfg!(feature = "help") && self.get_override_help().is_none() {
self.settings.insert(AppSettings::DisableHelpFlag.into()); self.settings.set(AppSettings::DisableHelpFlag);
self.settings self.settings.set(AppSettings::DisableHelpSubcommand);
.insert(AppSettings::DisableHelpSubcommand.into());
} }
if self.is_set(AppSettings::ArgsNegateSubcommands) { if self.is_set(AppSettings::ArgsNegateSubcommands) {
self.settings self.settings.set(AppSettings::SubcommandsNegateReqs);
.insert(AppSettings::SubcommandsNegateReqs.into());
} }
if self.external_value_parser.is_some() { if self.external_value_parser.is_some() {
self.settings self.settings.set(AppSettings::AllowExternalSubcommands);
.insert(AppSettings::AllowExternalSubcommands.into());
} }
if !self.has_subcommands() { if !self.has_subcommands() {
self.settings self.settings.set(AppSettings::DisableHelpSubcommand);
.insert(AppSettings::DisableHelpSubcommand.into());
} }
self._propagate(); self._propagate();
@ -3924,14 +3914,13 @@ impl Command {
let is_allow_negative_numbers_set = self.is_allow_negative_numbers_set(); let is_allow_negative_numbers_set = self.is_allow_negative_numbers_set();
for arg in self.args.args_mut() { for arg in self.args.args_mut() {
if is_allow_hyphen_values_set && arg.is_takes_value_set() { 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() { if is_allow_negative_numbers_set && arg.is_takes_value_set() {
arg.settings arg.settings.set(ArgSettings::AllowNegativeNumbers);
.insert(ArgSettings::AllowNegativeNumbers.into());
} }
if is_trailing_var_arg_set && arg.get_index() == Some(highest_idx) { if is_trailing_var_arg_set && arg.get_index() == Some(highest_idx) {
arg.settings.insert(ArgSettings::TrailingVarArg.into()); arg.settings.set(ArgSettings::TrailingVarArg);
} }
} }
} }

View file

@ -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")] #[cfg(feature = "debug")]
macro_rules! debug { macro_rules! debug {
($($arg:tt)*) => ({ ($($arg:tt)*) => ({