use crate::{
Boolean, Qrafting, Query, TypeMeta,
expression::{As, Column, ColumnStar, Expression},
query::{JoinOn, LowerProject, OnJoin, Table},
};
#[derive(Debug, Clone, Copy)]
pub struct Aliased<T: Alias> {
pub(crate) alias: &'static str,
pub(crate) inner: T,
}
impl<M: Qrafting> Aliased<Table<M>> {
pub const fn star(&self) -> As<ColumnStar<M>> {
As {
table: self.alias,
inner: ColumnStar {
marker: std::marker::PhantomData,
},
}
}
pub fn col<T: IntoColumn>(&self, col: T) -> As<T::Out> {
col.into_as(self.alias)
}
pub fn on<E>(&self, e: E) -> JoinOn<Self, E>
where
E: Expression,
E::Type: Boolean,
{
OnJoin::on(*self, e)
}
}
pub trait IntoColumn: Sized {
type Out;
fn into_as(self, alias: &'static str) -> As<Self::Out>;
}
impl<M, Ty: TypeMeta> IntoColumn for Column<M, Ty> {
type Out = Column<M, Ty>;
fn into_as(self, alias: &'static str) -> As<Self::Out> {
As {
table: alias,
inner: self,
}
}
}
impl IntoColumn for &'static str {
type Out = &'static str;
fn into_as(self, alias: &'static str) -> As<Self::Out> {
As {
table: alias,
inner: self,
}
}
}
impl<T: Alias> Aliased<T> {
pub const fn new(inner: T, alias: &'static str) -> Self {
Self { inner, alias }
}
}
pub trait Alias {
fn alias(self, alias: &'static str) -> Aliased<Self>
where
Self: Sized,
{
Aliased::new(self, alias)
}
}
impl Alias for Query {}
impl<T> Alias for T where T: LowerProject {}