use std::marker::PhantomData;
use super::Joiner;
pub struct Symmetric;
pub struct Directed;
pub fn equal<A, T, F>(key: F) -> EqualJoiner<F, F, T, Symmetric>
where
T: PartialEq,
F: Fn(&A) -> T + Clone + Send + Sync,
{
EqualJoiner {
left: key.clone(),
right: key,
_phantom: PhantomData,
}
}
pub fn equal_bi<T, Fa, Fb>(left: Fa, right: Fb) -> EqualJoiner<Fa, Fb, T, Directed>
where
T: PartialEq,
Fa: Send + Sync,
Fb: Send + Sync,
{
EqualJoiner {
left,
right,
_phantom: PhantomData,
}
}
pub fn equal_raw<Fa, Fb, T>(left: Fa, right: Fb) -> EqualJoiner<Fa, Fb, T, Directed>
where
T: PartialEq,
Fa: Send + Sync,
Fb: Send + Sync,
{
EqualJoiner {
left,
right,
_phantom: PhantomData,
}
}
pub fn equal_on<K2, LK, KC>(left: LK, right: KC) -> EqualJoiner<LK, KC, K2, Directed>
where
K2: PartialEq,
LK: Send + Sync,
KC: Send + Sync,
{
EqualJoiner {
left,
right,
_phantom: PhantomData,
}
}
pub struct EqualJoiner<Fa, Fb, T, Mode = Directed> {
left: Fa,
right: Fb,
_phantom: PhantomData<(fn() -> T, fn() -> Mode)>,
}
impl<Fa, Fb, T, Mode> EqualJoiner<Fa, Fb, T, Mode> {
pub fn and<J>(self, other: J) -> super::AndJoiner<Self, J> {
super::AndJoiner {
first: self,
second: other,
}
}
#[inline]
pub fn key_a<A>(&self, a: &A) -> T
where
Fa: Fn(&A) -> T,
{
(self.left)(a)
}
#[inline]
pub fn key_b<B>(&self, b: &B) -> T
where
Fb: Fn(&B) -> T,
{
(self.right)(b)
}
#[inline]
pub fn into_keys(self) -> (Fa, Fb) {
(self.left, self.right)
}
#[inline]
pub fn key_extractors(&self) -> (&Fa, &Fb) {
(&self.left, &self.right)
}
}
impl<A, B, T, Fa, Fb, Mode> Joiner<A, B> for EqualJoiner<Fa, Fb, T, Mode>
where
T: PartialEq,
Fa: Fn(&A) -> T + Send + Sync,
Fb: Fn(&B) -> T + Send + Sync,
{
#[inline]
fn matches(&self, a: &A, b: &B) -> bool {
(self.left)(a) == (self.right)(b)
}
}