Skip to content

Commit

Permalink
Remove bitflags dependency (#1436)
Browse files Browse the repository at this point in the history
The only real use of bitflags was to save a tiny bit of memory. It isn't
exposed externally and we can just use a flag enumeration combined with
a HashSet to replace it. Because of this, let's not subject this
dependency to all projects which depend on clap.
  • Loading branch information
Nathaniel McCallum authored and spacekookie committed Mar 27, 2019
1 parent e0e897a commit 6ba4772
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 157 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ is-it-maintained-open-issues = { repository = "clap-rs/clap" }
maintenance = {status = "actively-developed"}

[dependencies]
bitflags = "1.0"
unicode-width = "0.1.4"
textwrap = "0.10.0"
strsim = { version = "0.8", optional = true }
Expand Down
6 changes: 3 additions & 3 deletions src/app/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,8 @@ where
sc.p.set(AS::GlobalVersion);
sc.p.meta.version = Some(self.meta.version.unwrap());
}
sc.p.settings = sc.p.settings | self.g_settings;
sc.p.g_settings = sc.p.g_settings | self.g_settings;
sc.p.settings.update(&self.g_settings);
sc.p.g_settings.update(&self.g_settings);
sc.p.meta.term_w = self.meta.term_w;
sc.p.meta.max_w = self.meta.max_w;
}
Expand Down Expand Up @@ -767,7 +767,7 @@ where
pb.b.help = Some("The subcommand whose help message to display");
pb.set(ArgSettings::Multiple);
sc.positionals.insert(1, pb);
sc.settings = sc.settings | self.g_settings;
sc.settings.update(&self.g_settings);
} else {
sc.create_help_and_version();
}
Expand Down
198 changes: 100 additions & 98 deletions src/app/settings.rs
Original file line number Diff line number Diff line change
@@ -1,120 +1,122 @@
// Std
use std::collections::HashSet;
#[allow(deprecated, unused_imports)]
use std::ascii::AsciiExt;
use std::str::FromStr;
use std::ops::BitOr;

bitflags! {
struct Flags: u64 {
const SC_NEGATE_REQS = 1;
const SC_REQUIRED = 1 << 1;
const A_REQUIRED_ELSE_HELP = 1 << 2;
const GLOBAL_VERSION = 1 << 3;
const VERSIONLESS_SC = 1 << 4;
const UNIFIED_HELP = 1 << 5;
const WAIT_ON_ERROR = 1 << 6;
const SC_REQUIRED_ELSE_HELP= 1 << 7;
const NEEDS_LONG_HELP = 1 << 8;
const NEEDS_LONG_VERSION = 1 << 9;
const NEEDS_SC_HELP = 1 << 10;
const DISABLE_VERSION = 1 << 11;
const HIDDEN = 1 << 12;
const TRAILING_VARARG = 1 << 13;
const NO_BIN_NAME = 1 << 14;
const ALLOW_UNK_SC = 1 << 15;
const UTF8_STRICT = 1 << 16;
const UTF8_NONE = 1 << 17;
const LEADING_HYPHEN = 1 << 18;
const NO_POS_VALUES = 1 << 19;
const NEXT_LINE_HELP = 1 << 20;
const DERIVE_DISP_ORDER = 1 << 21;
const COLORED_HELP = 1 << 22;
const COLOR_ALWAYS = 1 << 23;
const COLOR_AUTO = 1 << 24;
const COLOR_NEVER = 1 << 25;
const DONT_DELIM_TRAIL = 1 << 26;
const ALLOW_NEG_NUMS = 1 << 27;
const LOW_INDEX_MUL_POS = 1 << 28;
const DISABLE_HELP_SC = 1 << 29;
const DONT_COLLAPSE_ARGS = 1 << 30;
const ARGS_NEGATE_SCS = 1 << 31;
const PROPAGATE_VALS_DOWN = 1 << 32;
const ALLOW_MISSING_POS = 1 << 33;
const TRAILING_VALUES = 1 << 34;
const VALID_NEG_NUM_FOUND = 1 << 35;
const PROPAGATED = 1 << 36;
const VALID_ARG_FOUND = 1 << 37;
const INFER_SUBCOMMANDS = 1 << 38;
const CONTAINS_LAST = 1 << 39;
const ARGS_OVERRIDE_SELF = 1 << 40;
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
enum Flags {
ScNegateReqs,
ScRequired,
ARequiredElseHelp,
GlobalVersion,
VersionlessSc,
UnifiedHelp,
WaitOnError,
ScRequiredElseHelp,
NeedsLongHelp,
NeedsLongVersion,
NeedsScHelp,
DisableVersion,
Hidden,
TrailingVararg,
NoBinName,
AllowUnkSc,
Utf8Strict,
Utf8None,
LeadingHyphen,
NoPosValues,
NextLineHelp,
DeriveDispOrder,
ColoredHelp,
ColorAlways,
ColorAuto,
ColorNever,
DontDelimTrail,
AllowNegNums,
LowIndexMulPos,
DisableHelpSc,
DontCollapseArgs,
ArgsNegateScs,
PropagateValsDown,
AllowMissingPos,
TrailingValues,
ValidNegNumFound,
Propagated,
ValidArgFound,
InferSubcommands,
ContainsLast,
ArgsOverrideSelf,
}

#[doc(hidden)]
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct AppFlags(Flags);

impl BitOr for AppFlags {
type Output = Self;
fn bitor(self, rhs: Self) -> Self { AppFlags(self.0 | rhs.0) }
}
#[derive(Debug, Clone, PartialEq)]
pub struct AppFlags(HashSet<Flags>);

impl Default for AppFlags {
fn default() -> Self {
AppFlags(
Flags::NEEDS_LONG_VERSION | Flags::NEEDS_LONG_HELP | Flags::NEEDS_SC_HELP
| Flags::UTF8_NONE | Flags::COLOR_AUTO,
)
let mut set = HashSet::new();
set.insert(Flags::NeedsLongVersion);
set.insert(Flags::NeedsLongHelp);
set.insert(Flags::NeedsScHelp);
set.insert(Flags::Utf8None);
set.insert(Flags::ColorAuto);
AppFlags(set)
}
}

#[allow(deprecated)]
impl AppFlags {
pub fn new() -> Self { AppFlags::default() }
pub fn zeroed() -> Self { AppFlags(Flags::empty()) }
pub fn zeroed() -> Self { AppFlags(HashSet::new()) }
pub fn update(&mut self, other: &Self) {
for flag in other.0.iter() {
self.0.insert(*flag);
}
}

impl_settings! { AppSettings,
ArgRequiredElseHelp => Flags::A_REQUIRED_ELSE_HELP,
ArgsNegateSubcommands => Flags::ARGS_NEGATE_SCS,
AllArgsOverrideSelf => Flags::ARGS_OVERRIDE_SELF,
AllowExternalSubcommands => Flags::ALLOW_UNK_SC,
AllowInvalidUtf8 => Flags::UTF8_NONE,
AllowLeadingHyphen => Flags::LEADING_HYPHEN,
AllowNegativeNumbers => Flags::ALLOW_NEG_NUMS,
AllowMissingPositional => Flags::ALLOW_MISSING_POS,
ColoredHelp => Flags::COLORED_HELP,
ColorAlways => Flags::COLOR_ALWAYS,
ColorAuto => Flags::COLOR_AUTO,
ColorNever => Flags::COLOR_NEVER,
DontDelimitTrailingValues => Flags::DONT_DELIM_TRAIL,
DontCollapseArgsInUsage => Flags::DONT_COLLAPSE_ARGS,
DeriveDisplayOrder => Flags::DERIVE_DISP_ORDER,
DisableHelpSubcommand => Flags::DISABLE_HELP_SC,
DisableVersion => Flags::DISABLE_VERSION,
GlobalVersion => Flags::GLOBAL_VERSION,
HidePossibleValuesInHelp => Flags::NO_POS_VALUES,
Hidden => Flags::HIDDEN,
LowIndexMultiplePositional => Flags::LOW_INDEX_MUL_POS,
NeedsLongHelp => Flags::NEEDS_LONG_HELP,
NeedsLongVersion => Flags::NEEDS_LONG_VERSION,
NeedsSubcommandHelp => Flags::NEEDS_SC_HELP,
NoBinaryName => Flags::NO_BIN_NAME,
PropagateGlobalValuesDown=> Flags::PROPAGATE_VALS_DOWN,
StrictUtf8 => Flags::UTF8_STRICT,
SubcommandsNegateReqs => Flags::SC_NEGATE_REQS,
SubcommandRequired => Flags::SC_REQUIRED,
SubcommandRequiredElseHelp => Flags::SC_REQUIRED_ELSE_HELP,
TrailingVarArg => Flags::TRAILING_VARARG,
UnifiedHelpMessage => Flags::UNIFIED_HELP,
NextLineHelp => Flags::NEXT_LINE_HELP,
VersionlessSubcommands => Flags::VERSIONLESS_SC,
WaitOnError => Flags::WAIT_ON_ERROR,
TrailingValues => Flags::TRAILING_VALUES,
ValidNegNumFound => Flags::VALID_NEG_NUM_FOUND,
Propagated => Flags::PROPAGATED,
ValidArgFound => Flags::VALID_ARG_FOUND,
InferSubcommands => Flags::INFER_SUBCOMMANDS,
ContainsLast => Flags::CONTAINS_LAST
ArgRequiredElseHelp => Flags::ARequiredElseHelp,
ArgsNegateSubcommands => Flags::ArgsNegateScs,
AllArgsOverrideSelf => Flags::ArgsOverrideSelf,
AllowExternalSubcommands => Flags::AllowUnkSc,
AllowInvalidUtf8 => Flags::Utf8None,
AllowLeadingHyphen => Flags::LeadingHyphen,
AllowNegativeNumbers => Flags::AllowNegNums,
AllowMissingPositional => Flags::AllowMissingPos,
ColoredHelp => Flags::ColoredHelp,
ColorAlways => Flags::ColorAlways,
ColorAuto => Flags::ColorAuto,
ColorNever => Flags::ColorNever,
DontDelimitTrailingValues => Flags::DontDelimTrail,
DontCollapseArgsInUsage => Flags::DontCollapseArgs,
DeriveDisplayOrder => Flags::DeriveDispOrder,
DisableHelpSubcommand => Flags::DisableHelpSc,
DisableVersion => Flags::DisableVersion,
GlobalVersion => Flags::GlobalVersion,
HidePossibleValuesInHelp => Flags::NoPosValues,
Hidden => Flags::Hidden,
LowIndexMultiplePositional => Flags::LowIndexMulPos,
NeedsLongHelp => Flags::NeedsLongHelp,
NeedsLongVersion => Flags::NeedsLongVersion,
NeedsSubcommandHelp => Flags::NeedsScHelp,
NoBinaryName => Flags::NoBinName,
PropagateGlobalValuesDown=> Flags::PropagateValsDown,
StrictUtf8 => Flags::Utf8Strict,
SubcommandsNegateReqs => Flags::ScNegateReqs,
SubcommandRequired => Flags::ScRequired,
SubcommandRequiredElseHelp => Flags::ScRequiredElseHelp,
TrailingVarArg => Flags::TrailingVararg,
UnifiedHelpMessage => Flags::UnifiedHelp,
NextLineHelp => Flags::NextLineHelp,
VersionlessSubcommands => Flags::VersionlessSc,
WaitOnError => Flags::WaitOnError,
TrailingValues => Flags::TrailingValues,
ValidNegNumFound => Flags::ValidNegNumFound,
Propagated => Flags::Propagated,
ValidArgFound => Flags::ValidArgFound,
InferSubcommands => Flags::InferSubcommands,
ContainsLast => Flags::ContainsLast
}
}

Expand Down
97 changes: 51 additions & 46 deletions src/args/settings.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,71 @@
// Std
use std::collections::HashSet;
#[allow(deprecated, unused_imports)]
use std::ascii::AsciiExt;
use std::str::FromStr;

bitflags! {
struct Flags: u32 {
const REQUIRED = 1;
const MULTIPLE = 1 << 1;
const EMPTY_VALS = 1 << 2;
const GLOBAL = 1 << 3;
const HIDDEN = 1 << 4;
const TAKES_VAL = 1 << 5;
const USE_DELIM = 1 << 6;
const NEXT_LINE_HELP = 1 << 7;
const R_UNLESS_ALL = 1 << 8;
const REQ_DELIM = 1 << 9;
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;
const HIDE_ENV_VALS = 1 << 17;
const HIDDEN_SHORT_H = 1 << 18;
const HIDDEN_LONG_H = 1 << 19;
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
enum Flags {
Required,
Multiple,
EmptyVals,
Global,
Hidden,
TakesVal,
UseDelim,
NextLineHelp,
RUnlessAll,
ReqDelim,
DelimNotSet,
HidePosVals,
AllowTacVals,
RequireEquals,
Last,
HideDefaultVal,
CaseInsensitive,
HideEnvVals,
HiddenShortH,
HiddenLongH
}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct ArgFlags(Flags);
#[derive(Debug, Clone)]
pub struct ArgFlags(HashSet<Flags>);

impl ArgFlags {
pub fn new() -> Self { ArgFlags::default() }

impl_settings!{ArgSettings,
Required => Flags::REQUIRED,
Multiple => Flags::MULTIPLE,
EmptyValues => Flags::EMPTY_VALS,
Global => Flags::GLOBAL,
Hidden => Flags::HIDDEN,
TakesValue => Flags::TAKES_VAL,
UseValueDelimiter => Flags::USE_DELIM,
NextLineHelp => Flags::NEXT_LINE_HELP,
RequiredUnlessAll => Flags::R_UNLESS_ALL,
RequireDelimiter => Flags::REQ_DELIM,
ValueDelimiterNotSet => Flags::DELIM_NOT_SET,
HidePossibleValues => Flags::HIDE_POS_VALS,
AllowLeadingHyphen => Flags::ALLOW_TAC_VALS,
RequireEquals => Flags::REQUIRE_EQUALS,
Last => Flags::LAST,
CaseInsensitive => Flags::CASE_INSENSITIVE,
HideEnvValues => Flags::HIDE_ENV_VALS,
HideDefaultValue => Flags::HIDE_DEFAULT_VAL,
HiddenShortHelp => Flags::HIDDEN_SHORT_H,
HiddenLongHelp => Flags::HIDDEN_LONG_H
Required => Flags::Required,
Multiple => Flags::Multiple,
EmptyValues => Flags::EmptyVals,
Global => Flags::Global,
Hidden => Flags::Hidden,
TakesValue => Flags::TakesVal,
UseValueDelimiter => Flags::UseDelim,
NextLineHelp => Flags::NextLineHelp,
RequiredUnlessAll => Flags::RUnlessAll,
RequireDelimiter => Flags::ReqDelim,
ValueDelimiterNotSet => Flags::DelimNotSet,
HidePossibleValues => Flags::HidePosVals,
AllowLeadingHyphen => Flags::AllowTacVals,
RequireEquals => Flags::RequireEquals,
Last => Flags::Last,
CaseInsensitive => Flags::CaseInsensitive,
HideEnvValues => Flags::HideEnvVals,
HideDefaultValue => Flags::HideDefaultVal,
HiddenShortHelp => Flags::HiddenShortH,
HiddenLongHelp => Flags::HiddenLongH
}
}

impl Default for ArgFlags {
fn default() -> Self { ArgFlags(Flags::EMPTY_VALS | Flags::DELIM_NOT_SET) }
fn default() -> Self {
let mut set = HashSet::new();
set.insert(Flags::EmptyVals);
set.insert(Flags::DelimNotSet);
ArgFlags(set)
}
}

/// Various settings that apply to arguments and may be set, unset, and checked via getter/setter
Expand Down
7 changes: 2 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,10 +519,9 @@
#![crate_type = "lib"]
#![doc(html_root_url = "https://docs.rs/clap/2.32.0")]
#![deny(missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts,
unused_import_braces, unused_allocation)]
unused_import_braces, unused_allocation, trivial_numeric_casts)]
// Lints we'd like to deny but are currently failing for upstream crates
// unused_qualifications (bitflags, clippy)
// trivial_numeric_casts (bitflags)
// unused_qualifications (clippy)
#![cfg_attr(not(any(feature = "lints", feature = "nightly")), forbid(unstable_features))]
#![cfg_attr(feature = "lints", feature(plugin))]
#![cfg_attr(feature = "lints", plugin(clippy))]
Expand All @@ -536,8 +535,6 @@
extern crate ansi_term;
#[cfg(feature = "color")]
extern crate atty;
#[macro_use]
extern crate bitflags;
#[cfg(feature = "suggestions")]
extern crate strsim;
#[cfg(feature = "wrap_help")]
Expand Down
Loading

0 comments on commit 6ba4772

Please sign in to comment.