dacquiri 0.5.1

An authorization framework with compile-time enforcement.
Documentation
use std::marker::PhantomData;
use crate::attribute::BaseAttribute;
use crate::error::ConstraintError;
use crate::has::{HasEntityWithType, ShedNext};
use crate::private::PrivateConstraintT;
use crate::store::EntityProof;

pub type EntityTag = &'static str;
pub type ConstraintResult<T> = Result<T, ConstraintError>;
pub trait ConstraintEntity = Send + Sync;


pub struct ConstraintChain<const STAG: EntityTag, const RTAG: EntityTag, Attr, Next> {
    next: Next,
    attr_phantom: PhantomData<Attr>
}

impl<const STAG: EntityTag, const RTAG: EntityTag, Attr, Next> ConstraintChain<STAG, RTAG, Attr, Next>
    where
        Attr: BaseAttribute,
        Next: ConstraintT
{
    pub(crate) fn new(next: Next) -> Self {
        Self {
            next,
            attr_phantom: PhantomData
        }
    }
}

pub trait ConstraintT: PrivateConstraintT + Sized {
    fn add_entity<T, const ETAG: EntityTag>(self, entity: T) -> ConstraintResult<EntityProof<ETAG, T, Self>>
        where
            T: ConstraintEntity + 'static;

    fn get_entity<T, const TAG: EntityTag>(&self) -> &T
        where
            T: ConstraintEntity + 'static,
            Self: HasEntityWithType<TAG, T>;

    fn get_entity_mut<T, const TAG: EntityTag>(&mut self) -> &mut T
        where
            T: ConstraintEntity + 'static,
            Self: HasEntityWithType<TAG, T>;

    fn try_get_entity<T, const TAG: EntityTag>(&self) -> ConstraintResult<&T>
        where
            T: ConstraintEntity + 'static;

    fn try_get_entity_mut<T, const TAG: EntityTag>(&mut self) -> ConstraintResult<&mut T>
        where
            T: ConstraintEntity + 'static;
}

impl<const STAG: EntityTag, const RTAG: EntityTag, Attr, Next> PrivateConstraintT for ConstraintChain<STAG, RTAG, Attr, Next>
    where
        Attr: BaseAttribute,
        Next: ConstraintT,
{
    fn _private_add_entity<T, const ETAG: EntityTag>(&mut self, entity: T) -> ConstraintResult<()>
        where
            T: ConstraintEntity + 'static
    {
        self.next._private_add_entity::<T, ETAG>(entity)
    }

    fn _private_get_entity_ref<T, const ETAG: EntityTag>(&self) -> &T
        where
            T: ConstraintEntity + 'static
    {
        self.next._private_get_entity_ref::<T, ETAG>()
    }

    fn _private_get_entity_mut<T, const ETAG: EntityTag>(&mut self) -> &mut T
        where
            T: ConstraintEntity + 'static
    {
        self.next._private_get_entity_mut::<T, ETAG>()
    }

    fn _private_get_entity<T, const ETAG: EntityTag>(&mut self) -> T
        where
            T: ConstraintEntity + 'static
    {
        self.next._private_get_entity::<T, ETAG>()
    }

    fn _private_try_get_entity_ref<T, const ETAG: EntityTag>(&self) -> ConstraintResult<&T>
        where
            T: ConstraintEntity + 'static
    {
        self.next._private_try_get_entity_ref::<T, ETAG>()
    }

    fn _private_try_get_entity_mut<T, const ETAG: EntityTag>(&mut self) -> ConstraintResult<&mut T>
        where
            T: ConstraintEntity + 'static
    {
        self.next._private_try_get_entity_mut::<T, ETAG>()
    }
}

impl<
    const STAG: EntityTag,
    const RTAG: EntityTag,
    Attr,
    Next
> ConstraintT for ConstraintChain<STAG, RTAG, Attr, Next>
    where
        Attr: BaseAttribute,
        Next: ConstraintT,
{
    fn add_entity<T, const ETAG: EntityTag>(mut self, entity: T) -> ConstraintResult<EntityProof<ETAG, T, Self>>
        where
            T: ConstraintEntity + 'static,
    {
        self._private_add_entity::<T, ETAG>(entity)
            .map(|_| EntityProof::<_, _, _>::new(self))
    }

    fn get_entity<T, const TAG: EntityTag>(&self) -> &T
        where
            T: ConstraintEntity + 'static,
            Self: HasEntityWithType<TAG, T>
    {
        self._private_get_entity_ref::<T, TAG>()
    }

    fn get_entity_mut<T, const TAG: EntityTag>(&mut self) -> &mut T
        where
            T: ConstraintEntity + 'static,
            Self: HasEntityWithType<TAG, T>
    {
        self._private_get_entity_mut::<T, TAG>()
    }

    fn try_get_entity<T, const TAG: EntityTag>(&self) -> ConstraintResult<&T>
        where
            T: ConstraintEntity + 'static
    {
        self._private_try_get_entity_ref::<T, TAG>()
    }

    fn try_get_entity_mut<T, const TAG: EntityTag>(&mut self) -> ConstraintResult<&mut T>
        where
            T: ConstraintEntity + 'static
    {
        self._private_try_get_entity_mut::<T, TAG>()
    }
}

impl<
    Next,
    ChainNext,
    EntityType,
    Attr,
    const STAG: EntityTag,
    const RTAG: EntityTag,
    const ETAG: EntityTag
> ShedNext<ETAG, EntityType, Next> for ConstraintChain<STAG, RTAG, Attr, ChainNext>
    where
        Attr: BaseAttribute,
        ChainNext: ShedNext<ETAG, EntityType, Next> + ConstraintT,
        EntityType: ConstraintEntity + 'static,
{
    fn shed(self) -> (EntityType, Next) {
        self.next.shed()
    }
}