core_extensions/type_asserts.rs
1//! Type-level assertions, most useful for tests.
2#![allow(clippy::type_complexity)]
3
4use crate::TypeIdentity;
5
6use std_::marker::PhantomData;
7
8
9/// Asserts that its 2 type parameters are the same type.
10///
11/// This assertion is done on the type level,
12/// so `let _: AssertEq<T, U>;` requires that `T` must be the same type as `U`.
13///
14/// # Example
15///
16/// ```
17/// use core_extensions::type_asserts::AssertEq;
18///
19/// trait ElemTy {
20/// type Elem;
21/// }
22///
23/// impl<A> ElemTy for (A,) {
24/// type Elem = A;
25/// }
26///
27/// let _: AssertEq<u32, <(u32,) as ElemTy>::Elem>;
28///
29/// let _ = AssertEq::new(&0u32, &0u32);
30///
31/// ```
32///
33/// # Non-compiling
34///
35/// ```compile_fail
36/// use core_extensions::type_asserts::AssertEq;
37///
38/// let _: AssertEq<(), u32>;
39/// let _ = AssertEq::new(&(), &0u32);
40///
41/// ```
42///
43/// ```compile_fail
44/// use core_extensions::type_asserts::AssertEq;
45///
46/// let _: AssertEq<u32, ()>;
47/// let _ = AssertEq::new(&0u32, &());
48///
49/// ```
50///
51pub struct AssertEq<L:?Sized,R:?Sized>
52where L:TypeIdentity<Type=R>
53{
54 _marker:PhantomData<(
55 PhantomData<L>,
56 PhantomData<R>,
57 )>,
58}
59
60impl<A> AssertEq<A,A>{
61 /// Constructs an `AssertEq`.
62 pub fn new(_: A, _: A)->Self{
63 Self{_marker: PhantomData}
64 }
65
66 /// Constructs an `AssertEq`.
67 pub const NEW: Self = Self{_marker: PhantomData};
68}
69
70
71/// Asserts that its 3 type parameters are the same type.
72///
73/// This assertion is done on the type level,
74/// so `let _: AssertEq3<A, B, C>;` requires that `A`, `B`, and `C` must be the same type.
75///
76/// # Example
77///
78/// ```
79/// use core_extensions::type_asserts::AssertEq3;
80///
81/// trait TypeParams {
82/// type First;
83/// type Second;
84/// }
85///
86/// impl<A, B> TypeParams for (A, B) {
87/// type First = A;
88/// type Second = B;
89/// }
90///
91/// type First<T> = <T as TypeParams>::First;
92///
93/// type Second<T> = <T as TypeParams>::Second;
94///
95/// let _: AssertEq3<u32, First<(u32, ())>, Second<((), u32)>>;
96///
97/// let _ = AssertEq3::new(&0u32, &0u32, &0u32);
98///
99/// ```
100///
101/// # Non-compiling
102///
103/// ```compile_fail
104/// # use core_extensions::type_asserts::AssertEq3;
105/// let _: AssertEq3<(), u32, u32>;
106/// let _ = AssertEq3::new(&(), &0u32, &0u32);
107/// ```
108///
109/// ```compile_fail
110/// # use core_extensions::type_asserts::AssertEq3;
111/// let _: AssertEq3<u32, (), u32>;
112/// let _ = AssertEq3::new(&0u32, &(), &0u32);
113/// ```
114///
115/// ```compile_fail
116/// # use core_extensions::type_asserts::AssertEq3;
117/// let _: AssertEq3<u32, u32, ()>;
118/// let _ = AssertEq3::new(&0u32, &0u32, &());
119/// ```
120///
121pub struct AssertEq3<A:?Sized,B:?Sized,C:?Sized>
122where
123 A:TypeIdentity<Type=B>,
124 A:TypeIdentity<Type=C>,
125{
126 _marker:PhantomData<(
127 PhantomData<A>,
128 PhantomData<B>,
129 PhantomData<C>,
130 )>,
131}
132
133impl<A> AssertEq3<A,A,A>{
134 /// Constructs an `AssertEq3`.
135 pub fn new(_: A, _: A, _: A)->Self{
136 Self{_marker: PhantomData}
137 }
138 /// Constructs an `AssertEq3`.
139 pub const NEW: Self = Self{_marker: PhantomData};
140}
141
142
143/// Asserts that its 4 type parameters are the same type.
144///
145/// This assertion is done on the type level,
146/// so `let _: AssertEq4<A, B, C, D>;` requires that
147/// `A`, `B`, `C`, and `D` must be the same type.
148///
149/// # Example
150///
151/// ```
152/// use core_extensions::type_asserts::AssertEq4;
153///
154/// trait TypeParams {
155/// type First;
156/// type Second;
157/// type Third;
158/// }
159///
160/// impl<A, B, C> TypeParams for (A, B, C) {
161/// type First = A;
162/// type Second = B;
163/// type Third = C;
164/// }
165///
166/// type First<T> = <T as TypeParams>::First;
167///
168/// type Second<T> = <T as TypeParams>::Second;
169///
170/// type Third<T> = <T as TypeParams>::Third;
171///
172/// let _: AssertEq4<
173/// u32,
174/// First <(u32, (), ())>,
175/// Second<((), u32, ())>,
176/// Third <((), (), u32)>,
177/// >;
178///
179/// let _ = AssertEq4::new(&0u32, &0u32, &0u32, &0u32);
180///
181/// ```
182///
183/// # Non-compiling
184///
185/// ```compile_fail
186/// # use core_extensions::type_asserts::AssertEq4;
187/// let _: AssertEq4<(), u32, u32, u32>;
188/// let _ = AssertEq4::new(&(), &0u32, &0u32, &0u32);
189/// ```
190///
191/// ```compile_fail
192/// # use core_extensions::type_asserts::AssertEq4;
193/// let _: AssertEq4<u32, (), u32, u32>;
194/// let _ = AssertEq4::new(&0u32, &(), &0u32, &0u32);
195/// ```
196///
197/// ```compile_fail
198/// # use core_extensions::type_asserts::AssertEq4;
199/// let _: AssertEq4<u32, u32, (), u32>;
200/// let _ = AssertEq4::new(&0u32, &0u32, &(), &0u32);
201/// ```
202///
203/// ```compile_fail
204/// # use core_extensions::type_asserts::AssertEq4;
205/// let _: AssertEq4<u32, u32, u32, ()>;
206/// let _ = AssertEq4::new(&0u32, &0u32, &0u32, &());
207/// ```
208///
209pub struct AssertEq4<A:?Sized,B:?Sized,C:?Sized,D:?Sized>
210where
211 A:TypeIdentity<Type=B>,
212 A:TypeIdentity<Type=C>,
213 A:TypeIdentity<Type=D>,
214{
215 _marker:PhantomData<(
216 PhantomData<A>,
217 PhantomData<B>,
218 PhantomData<C>,
219 PhantomData<D>,
220 )>,
221}
222
223impl<A> AssertEq4<A,A,A,A>{
224 /// Constructs an `AssertEq4`.
225 pub fn new(_: A, _: A, _: A, _: A)->Self{
226 Self{_marker: PhantomData}
227 }
228
229 /// Constructs an `AssertEq4`.
230 pub const NEW: Self = Self{_marker: PhantomData};
231}
232
233
234////////////////////////////////////////////////////////////////////////////////
235