use crate::entity::Entity;

pub trait TableAlias {
    type Columns;

    fn alias(&self) -> &'static str;
    fn c(&self) -> &'static Self::Columns;
}

pub struct NonNullTableAlias<E: Entity> {
    pub alias: &'static str,
    pub c: &'static E::Columns,
}

impl<E: Entity> NonNullTableAlias<E> {
    pub const fn new(alias: &'static str) -> NonNullTableAlias<E> {
        return NonNullTableAlias { alias, c: E::C };
    }

    pub const fn into_nullable(self) -> NullableTableAlias<E> {
        return NullableTableAlias::new(self.alias);
    }
}

impl<E: Entity> TableAlias for NonNullTableAlias<E> {
    type Columns = E::Columns;

    fn alias(&self) -> &'static str {
        return self.alias;
    }

    fn c(&self) -> &'static Self::Columns {
        return self.c;
    }
}

pub struct NullableTableAlias<E: Entity> {
    pub alias: &'static str,
    pub c: &'static E::Columns,
}

impl<E: Entity> NullableTableAlias<E> {
    pub const fn new(alias: &'static str) -> NullableTableAlias<E> {
        return NullableTableAlias { alias, c: E::C };
    }
}

impl<E: Entity> TableAlias for NullableTableAlias<E> {
    type Columns = E::Columns;

    fn alias(&self) -> &'static str {
        return self.alias;
    }

    fn c(&self) -> &'static Self::Columns {
        return self.c;
    }
}
