use std::marker::PhantomData;
use crate::{sql::Table, util::TypesNotEqual};
pub trait SelectableTables {}
pub trait SelectableTablesContains<T: Table>: SelectableTables {}
pub struct SelectableTablesCons<T: Table, N: SelectableTables>(PhantomData<T>, PhantomData<N>);
impl<T: Table> SelectableTables for T {}
impl<T: Table> SelectableTablesContains<T> for T {}
impl<T: Table, N: SelectableTables> SelectableTables for SelectableTablesCons<T, N> {}
impl<T: Table, N: SelectableTables> SelectableTablesContains<T> for SelectableTablesCons<T, N> {}
impl<T: Table, N: SelectableTables, InnerT: Table> SelectableTablesContains<InnerT>
for SelectableTablesCons<T, N>
where
N: SelectableTablesContains<InnerT>,
(T, InnerT): TypesNotEqual,
{
}
pub trait CombineSelectableTables<CombineWith: SelectableTables> {
type Combined: SelectableTables;
}
impl<T: Table + SelectableTables, CombineWith: SelectableTables>
CombineSelectableTables<CombineWith> for T
{
type Combined = SelectableTablesCons<T, CombineWith>;
}
pub type CombinedSelectableTables<A, B> = <A as CombineSelectableTables<B>>::Combined;
impl<
T: Table,
N: SelectableTables + CombineSelectableTables<CombineWith>,
CombineWith: SelectableTables,
> CombineSelectableTables<CombineWith> for SelectableTablesCons<T, N>
{
type Combined = SelectableTablesCons<T, CombinedSelectableTables<N, CombineWith>>;
}