From c4d7425de559cbdff85a173f46e3c73632b8a772 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Thu, 4 Apr 2024 19:08:16 +0900 Subject: [PATCH] matchers: abstract matcher combinators over Matcher trait In order to implement a fileset, we'll need owned variants of these matchers. We can of course let callers move Box into these adapters, but we might need to somehow clone Box. So, I simply made adapters generic. --- lib/src/matchers.rs | 46 +++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/lib/src/matchers.rs b/lib/src/matchers.rs index e87911e65..24284915b 100644 --- a/lib/src/matchers.rs +++ b/lib/src/matchers.rs @@ -72,6 +72,26 @@ pub trait Matcher: Sync { fn visit(&self, dir: &RepoPath) -> Visit; } +impl Matcher for &T { + fn matches(&self, file: &RepoPath) -> bool { + ::matches(self, file) + } + + fn visit(&self, dir: &RepoPath) -> Visit { + ::visit(self, dir) + } +} + +impl Matcher for Box { + fn matches(&self, file: &RepoPath) -> bool { + ::matches(self, file) + } + + fn visit(&self, dir: &RepoPath) -> Visit { + ::visit(self, dir) + } +} + #[derive(PartialEq, Eq, Debug)] pub struct NothingMatcher; @@ -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 { /// 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 DifferenceMatcher { + pub fn new(wanted: M1, unwanted: M2) -> Self { Self { wanted, unwanted } } } -impl Matcher for DifferenceMatcher<'_> { +impl Matcher for DifferenceMatcher { fn matches(&self, file: &RepoPath) -> bool { self.wanted.matches(file) && !self.unwanted.matches(file) } @@ -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 { + input1: M1, + input2: M2, } -impl<'input> IntersectionMatcher<'input> { - pub fn new(input1: &'input dyn Matcher, input2: &'input dyn Matcher) -> Self { +impl IntersectionMatcher { + pub fn new(input1: M1, input2: M2) -> Self { Self { input1, input2 } } } -impl Matcher for IntersectionMatcher<'_> { +impl Matcher for IntersectionMatcher { fn matches(&self, file: &RepoPath) -> bool { self.input1.matches(file) && self.input2.matches(file) }