proc-macro-assertions 0.1.5

Easily create asserts on proc macro inputs
Documentation
use better_any::TidAble;

use crate::{
    add_generics::WithGenerics, assertable::Assertable, generatable::Generatable,
    into_template::TypeEq, maybe_borrowed::MaybeBorrowed, raw_assert::r#trait::RawAssertable,
    raw_assert::RawAssert,
};

/// One of the Assert types provided by the crate, at
/// this point in time also the only one.
///
/// This is backed by some template that the the
/// type is checked against.
///
/// Every template must implement [`Generatable`]
/// so that it can be turned into tokens that actually
/// check if the type matches the template.
///
/// Further information about the structure of this crate
/// can be found in the module documentation.
pub struct Assert<'a, T, A>
where
    T: Generatable<'a, A>,
    A: 'a + TidAble<'a>,
{
    pub template: MaybeBorrowed<'a, T>,
    pub assert: MaybeBorrowed<'a, A>,
}

pub trait InsertIntoTemplate<'a, T, A>
where
    T: Generatable<'a, A> + 'a,
    A: 'a + TidAble<'a>,
{
    /// The type of the Assert generated by the Template
    /// `Self`
    type Output: RawAssertable<'a>;

    /// Test some type against the template `Self` and turn
    /// it into [`Self::Output`]. So that the type may
    /// either be borrowed or owned, any type that
    /// can be turned into `MaybeBorrowed<T::Assert>`
    fn test<B>(self, ty: impl Into<MaybeBorrowed<'a, A>>) -> Self::Output
    where
        B: TypeEq<This = A>;
}

impl<'a, T, A> InsertIntoTemplate<'a, T, A> for T
where
    T: Generatable<'a, A> + 'a + Ord + Eq,
    A: Ord + Eq + 'a + TidAble<'a>,
{
    type Output = Assert<'a, T, A>;

    fn test<B>(self, ty: impl Into<MaybeBorrowed<'a, A>>) -> Assert<'a, T, A>
    where
        B: TypeEq<This = A>,
    {
        Assert {
            template: MaybeBorrowed::Owned(self),
            assert: ty.into(),
        }
    }
}

impl<'a, T, A> InsertIntoTemplate<'a, T, A> for &'a T
where
    T: Generatable<'a, A> + 'a + Ord + Eq,
    A: Ord + Eq + 'a + TidAble<'a>,
{
    type Output = Assert<'a, T, A>;

    fn test<B>(self, ty: impl Into<MaybeBorrowed<'a, A>>) -> Assert<'a, T, A>
    where
        B: TypeEq<This = A>,
    {
        Assert {
            template: MaybeBorrowed::Borrowed(self),
            assert: ty.into(),
        }
    }
}

impl<'a, T, A> InsertIntoTemplate<'a, T, A> for WithGenerics<'a, T>
where
    T: Generatable<'a, A> + Eq + Ord,
    A: Eq + Ord + 'a + TidAble<'a>,
{
    type Output = RawAssert<'a, T, A>;

    fn test<B>(self, ty: impl Into<MaybeBorrowed<'a, A>>) -> RawAssert<'a, T, A>
    where
        B: TypeEq<This = A>,
    {
        RawAssert {
            template: self.data.into(),
            generics: self.generics,
            assert: ty.into(),
        }
    }
}

impl<'a, T, A> InsertIntoTemplate<'a, T, A> for WithGenerics<'a, MaybeBorrowed<'a, T>>
where
    T: Generatable<'a, A> + Eq + Ord,
    A: Eq + Ord + 'a + TidAble<'a>,
{
    type Output = WithGenerics<'a, Assert<'a, T, A>>;

    fn test<B>(self, ty: impl Into<MaybeBorrowed<'a, A>>) -> WithGenerics<'a, Assert<'a, T, A>>
    where
        B: TypeEq<This = A>,
    {
        WithGenerics {
            data: Assert {
                template: self.data,
                assert: ty.into(),
            },
            generics: self.generics,
        }
    }
}

impl<'a, T, A> Assertable<'a> for Assert<'a, T, A>
where
    T: Generatable<'a, A> + Eq + Ord,
    A: Eq + Ord + TidAble<'a>,
{
    type Output = RawAssert<'a, T, A>;

    fn do_assert(self) -> Self::Output {
        RawAssert {
            template: self.template,
            generics: None,
            assert: self.assert,
        }
    }
}