use std::{hash::Hash, marker::PhantomData};
use crate::traits::CellValue;
pub trait Cardinality: Send + Sync + 'static {}
pub struct ExactlyOne;
pub struct ZeroOrOne;
pub struct Many;
impl Cardinality for ExactlyOne {}
impl Cardinality for ZeroOrOne {}
impl Cardinality for Many {}
pub trait Partition: Send + Sync + 'static {}
pub struct ByMapKey<K>(PhantomData<fn() -> K>);
pub struct ByRelation<Rel>(PhantomData<fn() -> Rel>);
pub struct Repartition<K>(PhantomData<fn() -> K>);
impl<K: Send + Sync + 'static> Partition for ByMapKey<K> {}
impl<Rel: Send + Sync + 'static> Partition for ByRelation<Rel> {}
impl<K: Send + Sync + 'static> Partition for Repartition<K> {}
pub trait PlanProperties {
type Cardinality: Cardinality;
type InputPartition: Partition;
type OutputPartition: Partition;
}
pub trait PreservesMapKey<K>: PlanProperties<OutputPartition = ByMapKey<K>>
where
K: Hash + Eq + CellValue,
{
}
impl<K, P> PreservesMapKey<K> for P
where
K: Hash + Eq + CellValue,
P: PlanProperties<OutputPartition = ByMapKey<K>>,
{
}