proc_macro_assertions/bounds/
mod.rs

1use std::marker::PhantomData;
2
3use crate::{
4    assertable::Assertable, maybe_borrowed::MaybeBorrowed, raw_assert::r#trait::RawAssertable,
5};
6
7/// This Trait represents something that is assertable with some additional data. See [`Assertable`] for general details.
8#[allow(clippy::module_name_repetitions)]
9pub trait AssertableWithBounds<'a, T> {
10    /// The output of the assertion
11    type Output: RawAssertable<'a>;
12
13    /// Do the assertion with the given bounds
14    fn do_assert(&self, bounds: T) -> Self::Output;
15}
16
17impl<'a, T, U> AssertableWithBounds<'a, T> for &'a U
18where
19    U: AssertableWithBounds<'a, T>,
20{
21    type Output = U::Output;
22
23    fn do_assert(&self, bounds: T) -> Self::Output {
24        (*self).do_assert(bounds)
25    }
26}
27
28/// This struct represents something that is assertable with some additional data, where that data was provided.
29#[allow(clippy::module_name_repetitions)]
30pub struct ResolvedBounds<'a, T, U>
31where
32    U: AssertableWithBounds<'a, T>,
33{
34    bounds: T,
35    assertable: MaybeBorrowed<'a, U>,
36    _lt: PhantomData<&'a ()>,
37}
38
39impl<'a, T, U> ResolvedBounds<'a, T, U>
40where
41    U: AssertableWithBounds<'a, T>,
42{
43    const fn new(bounds: T, assertable: MaybeBorrowed<'a, U>) -> Self {
44        Self {
45            bounds,
46            assertable,
47            _lt: PhantomData,
48        }
49    }
50}
51
52impl<'a, T, U> Assertable<'a> for ResolvedBounds<'a, T, U>
53where
54    U: AssertableWithBounds<'a, T>,
55{
56    type Output = <U as AssertableWithBounds<'a, T>>::Output;
57
58    fn do_assert(self) -> Self::Output {
59        self.assertable.do_assert(self.bounds)
60    }
61}
62
63#[allow(clippy::module_name_repetitions)]
64pub trait ProvideBounds<'a, T>
65where
66    Self: Sized + AssertableWithBounds<'a, T>,
67{
68    fn provide_bounds(self, bounds: T) -> ResolvedBounds<'a, T, Self>;
69}
70
71impl<'a, T, U> ProvideBounds<'a, T> for U
72where
73    U: Sized + AssertableWithBounds<'a, T>,
74{
75    fn provide_bounds(self, bounds: T) -> ResolvedBounds<'a, T, Self> {
76        ResolvedBounds::new(bounds, self.into())
77    }
78}
79
80#[allow(clippy::module_name_repetitions)]
81pub trait ResolveBounds<'a, T>
82where
83    Self: Sized,
84    T: Sized + AssertableWithBounds<'a, Self> + 'a,
85{
86    fn resolve_for(
87        self,
88        assertable: impl Into<MaybeBorrowed<'a, T>>,
89    ) -> ResolvedBounds<'a, Self, T>;
90}
91
92impl<'a, T, U> ResolveBounds<'a, T> for U
93where
94    T: Sized + AssertableWithBounds<'a, Self> + 'a,
95    Self: Sized,
96{
97    fn resolve_for(
98        self,
99        assertable: impl Into<MaybeBorrowed<'a, T>>,
100    ) -> ResolvedBounds<'a, Self, T> {
101        ResolvedBounds::new(self, assertable.into())
102    }
103}