proc-macro-assertions 0.1.5

Easily create asserts on proc macro inputs
Documentation
use std::ops::Deref;

use better_any::tid;
use quote::ToTokens;

use crate::{generatable::StaticTid, maybe_borrowed::MaybeBorrowed};

#[repr(transparent)]
pub struct TokenCmpWrapper<T: ToTokens>(pub T);

tid!(
    impl<'a, T: 'static> Tid<'a> for TokenCmpWrapper<T>  where T: ToTokens
);

impl<T> Deref for TokenCmpWrapper<T>
where
    T: ToTokens,
{
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<T, U> PartialEq<TokenCmpWrapper<U>> for TokenCmpWrapper<T>
where
    T: ToTokens,
    U: ToTokens,
{
    fn eq(&self, other: &TokenCmpWrapper<U>) -> bool {
        self.0.to_token_stream().to_string() == other.0.to_token_stream().to_string()
    }
}

impl<T> Eq for TokenCmpWrapper<T> where T: ToTokens {}

impl<T> Ord for TokenCmpWrapper<T>
where
    T: ToTokens,
{
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.0
            .to_token_stream()
            .to_string()
            .cmp(&other.0.to_token_stream().to_string())
    }
}

impl<T> PartialOrd for TokenCmpWrapper<T>
where
    T: ToTokens,
{
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl<U> From<U> for TokenCmpWrapper<U>
where
    U: ToTokens,
{
    fn from(value: U) -> Self {
        Self(value)
    }
}

impl<'a, U> From<&'a U> for &'a TokenCmpWrapper<U>
where
    U: ToTokens,
{
    fn from(value: &'a U) -> Self {
        // Safety: This is safe becaause of #[repr(transparent)].
        unsafe { &*(value as *const U).cast::<TokenCmpWrapper<U>>() }
    }
}

impl<'a, U> From<&'a mut U> for &'a mut TokenCmpWrapper<U>
where
    U: ToTokens,
{
    fn from(value: &'a mut U) -> Self {
        // Safety: This is safe becaause of #[repr(transparent)].
        unsafe { &mut *(value as *mut U).cast::<TokenCmpWrapper<U>>() }
    }
}

impl<'a, U> From<&'a U> for MaybeBorrowed<'a, TokenCmpWrapper<U>>
where
    U: ToTokens,
{
    fn from(value: &'a U) -> Self {
        MaybeBorrowed::Borrowed(value.into())
    }
}

impl<'a, T> From<T> for MaybeBorrowed<'a, TokenCmpWrapper<T>>
where
    T: ToTokens,
{
    fn from(value: T) -> Self {
        MaybeBorrowed::Owned(TokenCmpWrapper(value))
    }
}

impl<U> From<U> for TokenCmpWrapper<StaticTid<U>>
where
    U: ToTokens,
{
    fn from(value: U) -> Self {
        Self(value.into())
    }
}

impl<'a, U> From<&'a U> for &'a TokenCmpWrapper<StaticTid<U>>
where
    U: ToTokens,
{
    fn from(value: &'a U) -> Self {
        <&'a StaticTid<U>>::from(value).into()
    }
}

impl<'a, U> From<&'a mut U> for &'a mut TokenCmpWrapper<StaticTid<U>>
where
    U: ToTokens,
{
    fn from(value: &'a mut U) -> Self {
        <&'a mut StaticTid<U>>::from(value).into()
    }
}

impl<'a, U> From<&'a U> for MaybeBorrowed<'a, TokenCmpWrapper<StaticTid<U>>>
where
    U: ToTokens,
{
    fn from(value: &'a U) -> Self {
        // Safety: This is safe becaause of #[repr(transparent)].
        MaybeBorrowed::Borrowed(value.into())
    }
}

impl<'a, U> From<U> for MaybeBorrowed<'a, TokenCmpWrapper<StaticTid<U>>>
where
    U: ToTokens,
{
    fn from(value: U) -> Self {
        MaybeBorrowed::Owned(TokenCmpWrapper(value.into()))
    }
}

impl<'a, U> From<&'a U> for &'a StaticTid<TokenCmpWrapper<U>>
where
    U: ToTokens,
{
    fn from(value: &'a U) -> Self {
        <&'a TokenCmpWrapper<U>>::from(value).into()
    }
}

impl<'a, U> From<&'a mut U> for &'a mut StaticTid<TokenCmpWrapper<U>>
where
    U: ToTokens,
{
    fn from(value: &'a mut U) -> Self {
        <&'a mut TokenCmpWrapper<U>>::from(value).into()
    }
}

impl<'a, U> From<&'a U> for MaybeBorrowed<'a, StaticTid<TokenCmpWrapper<U>>>
where
    U: ToTokens,
{
    fn from(value: &'a U) -> Self {
        // Safety: This is safe becaause of #[repr(transparent)].
        MaybeBorrowed::Borrowed(value.into())
    }
}

impl<'a, U> From<U> for MaybeBorrowed<'a, StaticTid<TokenCmpWrapper<U>>>
where
    U: ToTokens,
{
    fn from(value: U) -> Self {
        MaybeBorrowed::Owned(StaticTid(value.into()))
    }
}

impl<T> ToTokens for TokenCmpWrapper<T>
where
    T: ToTokens,
{
    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
        (**self).to_tokens(tokens);
    }

    fn to_token_stream(&self) -> proc_macro2::TokenStream {
        (**self).to_token_stream()
    }

    fn into_token_stream(self) -> proc_macro2::TokenStream
    where
        Self: Sized,
    {
        self.to_token_stream()
    }
}