pub trait Joiner<A, B>: Send + Sync {
fn matches(&self, a: &A, b: &B) -> bool;
fn and<J>(self, other: J) -> AndJoiner<Self, J>
where
Self: Sized,
J: Joiner<A, B>,
{
AndJoiner {
first: self,
second: other,
}
}
}
pub struct AndJoiner<J1, J2> {
first: J1,
second: J2,
}
impl<A, B, J1, J2> Joiner<A, B> for AndJoiner<J1, J2>
where
J1: Joiner<A, B>,
J2: Joiner<A, B>,
{
#[inline]
fn matches(&self, a: &A, b: &B) -> bool {
self.first.matches(a, b) && self.second.matches(a, b)
}
}
pub struct FnJoiner<F> {
f: F,
}
impl<F> FnJoiner<F> {
pub fn new(f: F) -> Self {
Self { f }
}
}
impl<A, B, F> Joiner<A, B> for FnJoiner<F>
where
F: Fn(&A, &B) -> bool + Send + Sync,
{
#[inline]
fn matches(&self, a: &A, b: &B) -> bool {
(self.f)(a, b)
}
}