proc_macro_assertions/
assert.rs

1use better_any::TidAble;
2
3use crate::{
4    add_generics::WithGenerics, assertable::Assertable, generatable::Generatable,
5    into_template::TypeEq, maybe_borrowed::MaybeBorrowed, raw_assert::r#trait::RawAssertable,
6    raw_assert::RawAssert,
7};
8
9/// One of the Assert types provided by the crate, at
10/// this point in time also the only one.
11///
12/// This is backed by some template that the the
13/// type is checked against.
14///
15/// Every template must implement [`Generatable`]
16/// so that it can be turned into tokens that actually
17/// check if the type matches the template.
18///
19/// Further information about the structure of this crate
20/// can be found in the module documentation.
21pub struct Assert<'a, T, A>
22where
23    T: Generatable<'a, A>,
24    A: 'a + TidAble<'a>,
25{
26    pub template: MaybeBorrowed<'a, T>,
27    pub assert: MaybeBorrowed<'a, A>,
28}
29
30pub trait InsertIntoTemplate<'a, T, A>
31where
32    T: Generatable<'a, A> + 'a,
33    A: 'a + TidAble<'a>,
34{
35    /// The type of the Assert generated by the Template
36    /// `Self`
37    type Output: RawAssertable<'a>;
38
39    /// Test some type against the template `Self` and turn
40    /// it into [`Self::Output`]. So that the type may
41    /// either be borrowed or owned, any type that
42    /// can be turned into `MaybeBorrowed<T::Assert>`
43    fn test<B>(self, ty: impl Into<MaybeBorrowed<'a, A>>) -> Self::Output
44    where
45        B: TypeEq<This = A>;
46}
47
48impl<'a, T, A> InsertIntoTemplate<'a, T, A> for T
49where
50    T: Generatable<'a, A> + 'a + Ord + Eq,
51    A: Ord + Eq + 'a + TidAble<'a>,
52{
53    type Output = Assert<'a, T, A>;
54
55    fn test<B>(self, ty: impl Into<MaybeBorrowed<'a, A>>) -> Assert<'a, T, A>
56    where
57        B: TypeEq<This = A>,
58    {
59        Assert {
60            template: MaybeBorrowed::Owned(self),
61            assert: ty.into(),
62        }
63    }
64}
65
66impl<'a, T, A> InsertIntoTemplate<'a, T, A> for &'a T
67where
68    T: Generatable<'a, A> + 'a + Ord + Eq,
69    A: Ord + Eq + 'a + TidAble<'a>,
70{
71    type Output = Assert<'a, T, A>;
72
73    fn test<B>(self, ty: impl Into<MaybeBorrowed<'a, A>>) -> Assert<'a, T, A>
74    where
75        B: TypeEq<This = A>,
76    {
77        Assert {
78            template: MaybeBorrowed::Borrowed(self),
79            assert: ty.into(),
80        }
81    }
82}
83
84impl<'a, T, A> InsertIntoTemplate<'a, T, A> for WithGenerics<'a, T>
85where
86    T: Generatable<'a, A> + Eq + Ord,
87    A: Eq + Ord + 'a + TidAble<'a>,
88{
89    type Output = RawAssert<'a, T, A>;
90
91    fn test<B>(self, ty: impl Into<MaybeBorrowed<'a, A>>) -> RawAssert<'a, T, A>
92    where
93        B: TypeEq<This = A>,
94    {
95        RawAssert {
96            template: self.data.into(),
97            generics: self.generics,
98            assert: ty.into(),
99        }
100    }
101}
102
103impl<'a, T, A> InsertIntoTemplate<'a, T, A> for WithGenerics<'a, MaybeBorrowed<'a, T>>
104where
105    T: Generatable<'a, A> + Eq + Ord,
106    A: Eq + Ord + 'a + TidAble<'a>,
107{
108    type Output = WithGenerics<'a, Assert<'a, T, A>>;
109
110    fn test<B>(self, ty: impl Into<MaybeBorrowed<'a, A>>) -> WithGenerics<'a, Assert<'a, T, A>>
111    where
112        B: TypeEq<This = A>,
113    {
114        WithGenerics {
115            data: Assert {
116                template: self.data,
117                assert: ty.into(),
118            },
119            generics: self.generics,
120        }
121    }
122}
123
124impl<'a, T, A> Assertable<'a> for Assert<'a, T, A>
125where
126    T: Generatable<'a, A> + Eq + Ord,
127    A: Eq + Ord + TidAble<'a>,
128{
129    type Output = RawAssert<'a, T, A>;
130
131    fn do_assert(self) -> Self::Output {
132        RawAssert {
133            template: self.template,
134            generics: None,
135            assert: self.assert,
136        }
137    }
138}