1
0
mirror of https://github.com/BurntSushi/ripgrep.git synced 2025-11-23 21:54:45 +02:00

globset: make GlobSet::new public

For users of globset who already have a `Vec<Glob>` (or similar),
the current API requires them to iterate over their `Vec<Glob>`,
calling `GlobSetBuilder::add` for each `Glob`, thus constructing a new
`Vec<Glob>` internal to the GlobSetBuilder. This makes the consuming
code unnecessarily verbose. (There is unlikely to be any meaningful
performance impact of this, however, since the cost of allocating a new
`Vec` is likely marginal compared to the cost of glob compilation.)

Instead of taking a `&[Glob]`, we accept an iterator of anything that
can be borrowed as a `&Glob`. This required some light refactoring of
the constructor, but nothing onerous.

Closes #3066
This commit is contained in:
Ben Heidemann
2025-06-12 16:10:23 +01:00
committed by Andrew Gallant
parent 33b44812c0
commit 859d54270e
2 changed files with 25 additions and 6 deletions

View File

@@ -80,6 +80,12 @@ pub struct Glob {
tokens: Tokens,
}
impl AsRef<Glob> for Glob {
fn as_ref(&self) -> &Glob {
self
}
}
impl PartialEq for Glob {
fn eq(&self, other: &Glob) -> bool {
self.glob == other.glob && self.opts == other.opts

View File

@@ -455,10 +455,20 @@ impl GlobSet {
into.dedup();
}
fn new(pats: &[Glob]) -> Result<GlobSet, Error> {
if pats.is_empty() {
return Ok(GlobSet { len: 0, strats: vec![] });
/// Builds a new matcher from a collection of Glob patterns.
///
/// Once a matcher is built, no new patterns can be added to it.
pub fn new<I, G>(globs: I) -> Result<GlobSet, Error>
where
I: IntoIterator<Item = G>,
G: AsRef<Glob>,
{
let mut it = globs.into_iter().peekable();
if it.peek().is_none() {
return Ok(GlobSet::empty());
}
let mut len = 0;
let mut lits = LiteralStrategy::new();
let mut base_lits = BasenameLiteralStrategy::new();
let mut exts = ExtensionStrategy::new();
@@ -466,7 +476,10 @@ impl GlobSet {
let mut suffixes = MultiStrategyBuilder::new();
let mut required_exts = RequiredExtensionStrategyBuilder::new();
let mut regexes = MultiStrategyBuilder::new();
for (i, p) in pats.iter().enumerate() {
for (i, p) in it.enumerate() {
len += 1;
let p = p.as_ref();
match MatchStrategy::new(p) {
MatchStrategy::Literal(lit) => {
lits.add(i, lit);
@@ -532,7 +545,7 @@ impl GlobSet {
strats.push(GlobSetMatchStrategy::Regex(regexes.regex_set()?));
}
Ok(GlobSet { len: pats.len(), strats })
Ok(GlobSet { len, strats })
}
}
@@ -562,7 +575,7 @@ impl GlobSetBuilder {
///
/// Once a matcher is built, no new patterns can be added to it.
pub fn build(&self) -> Result<GlobSet, Error> {
GlobSet::new(&self.pats)
GlobSet::new(self.pats.iter())
}
/// Add a new pattern to this set.