Skip to content

Commit

Permalink
matchers: abstract matcher combinators over Matcher trait
Browse files Browse the repository at this point in the history
In order to implement a fileset, we'll need owned variants of these matchers.
We can of course let callers move Box<dyn Matcher> into these adapters, but
we might need to somehow clone Box<dyn Matcher>. So, I simply made adapters
generic.
  • Loading branch information
yuja committed Apr 5, 2024
1 parent db14f33 commit c4d7425
Showing 1 changed file with 34 additions and 12 deletions.
46 changes: 34 additions & 12 deletions lib/src/matchers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,26 @@ pub trait Matcher: Sync {
fn visit(&self, dir: &RepoPath) -> Visit;
}

impl<T: Matcher + ?Sized> Matcher for &T {
fn matches(&self, file: &RepoPath) -> bool {
<T as Matcher>::matches(self, file)
}

fn visit(&self, dir: &RepoPath) -> Visit {
<T as Matcher>::visit(self, dir)
}
}

impl<T: Matcher + ?Sized> Matcher for Box<T> {
fn matches(&self, file: &RepoPath) -> bool {
<T as Matcher>::matches(self, file)
}

fn visit(&self, dir: &RepoPath) -> Visit {
<T as Matcher>::visit(self, dir)
}
}

#[derive(PartialEq, Eq, Debug)]
pub struct NothingMatcher;

Expand Down Expand Up @@ -162,20 +182,21 @@ impl Matcher for PrefixMatcher {

/// Matches paths that are matched by the first input matcher but not by the
/// second.
pub struct DifferenceMatcher<'input> {
#[derive(Clone, Debug)]
pub struct DifferenceMatcher<M1, M2> {
/// The minuend
wanted: &'input dyn Matcher,
wanted: M1,
/// The subtrahend
unwanted: &'input dyn Matcher,
unwanted: M2,
}

impl<'input> DifferenceMatcher<'input> {
pub fn new(wanted: &'input dyn Matcher, unwanted: &'input dyn Matcher) -> Self {
impl<M1: Matcher, M2: Matcher> DifferenceMatcher<M1, M2> {
pub fn new(wanted: M1, unwanted: M2) -> Self {
Self { wanted, unwanted }
}
}

impl Matcher for DifferenceMatcher<'_> {
impl<M1: Matcher, M2: Matcher> Matcher for DifferenceMatcher<M1, M2> {
fn matches(&self, file: &RepoPath) -> bool {
self.wanted.matches(file) && !self.unwanted.matches(file)
}
Expand All @@ -196,18 +217,19 @@ impl Matcher for DifferenceMatcher<'_> {
}

/// Matches paths that are matched by both input matchers.
pub struct IntersectionMatcher<'input> {
input1: &'input dyn Matcher,
input2: &'input dyn Matcher,
#[derive(Clone, Debug)]
pub struct IntersectionMatcher<M1, M2> {
input1: M1,
input2: M2,
}

impl<'input> IntersectionMatcher<'input> {
pub fn new(input1: &'input dyn Matcher, input2: &'input dyn Matcher) -> Self {
impl<M1: Matcher, M2: Matcher> IntersectionMatcher<M1, M2> {
pub fn new(input1: M1, input2: M2) -> Self {
Self { input1, input2 }
}
}

impl Matcher for IntersectionMatcher<'_> {
impl<M1: Matcher, M2: Matcher> Matcher for IntersectionMatcher<M1, M2> {
fn matches(&self, file: &RepoPath) -> bool {
self.input1.matches(file) && self.input2.matches(file)
}
Expand Down

0 comments on commit c4d7425

Please sign in to comment.