mem-query 0.0.1

Relational algebra interface for Rust collections
use std::{
    marker::PhantomData,
};
use crate::{
    header::{Header, ProjectFrom, HasCol},
    record::{Record, Col, ExternalRecord},
    rename_col::RenameCol,
};

pub struct Rename<I,A,B> {
    pub(crate) inner: I,
    pub(crate) cols: PhantomData<(A,B)>
}

impl<I,A,B> Copy for Rename<I,A,B> where I:Copy {}
impl<I,A,B> Clone for Rename<I,A,B> where I:Clone {
    fn clone(&self)->Self {
        Rename { inner: self.inner.clone(), cols: PhantomData }
    }
}

impl<I,A:Col,B:Col<Inner = A::Inner>> Rename<I,A,B> {
    pub fn new(inner: I)->Self
    where I: Clone + Record,
        I::Cols: RenameCol<A,B>,
        <I::Cols as RenameCol<A,B>>::Renamed: Header
    {
        Self { inner, cols: PhantomData }
    }
}

impl<I,A,B> Record for Rename<I,A,B>
where I: Record,
    A: Col, B:Col<Inner=A::Inner>,
    I::Cols: RenameCol<A,B>,
    <I::Cols as RenameCol<A,B>>::Renamed: Header
{
    type Cols = <I::Cols as RenameCol<A,B>>::Renamed;

    #[inline(always)]
    fn col_opt<C:Col>(&self)->Option<&C> {
        use std::any::{TypeId, Any};
        if TypeId::of::<C>() == TypeId::of::<B>() {
            self.inner.col_opt::<A>()
                .and_then(|a| (a.rename_ref::<B>() as &dyn Any).downcast_ref())
        } 
        else if Self::Cols::has_col::<C>() {
            self.inner.col_opt()
        } else {
            None
        }
    }
}

impl<'a, I,A,B> ExternalRecord<'a> for Rename<I,A,B>
where I: ExternalRecord<'a>,
    A: Col, B:Col<Inner=A::Inner>,
    I::Cols: RenameCol<A,B>,
    <I::Cols as RenameCol<A,B>>::Renamed: Header
{
    #[inline(always)]
    fn ext_col_opt<C:Col>(&self)->Option<&'a C> {
        use std::any::{TypeId, Any};
        if TypeId::of::<C>() == TypeId::of::<B>() {
            self.inner.ext_col_opt::<A>()
                .and_then(|a| (a.rename_ref::<B>() as &dyn Any).downcast_ref())
        } 
        else if Self::Cols::has_col::<C>() {
            self.inner.ext_col_opt()
        } else {
            None
        }
    }
}