1#[macro_export]
20macro_rules! make_trait_kind {
21 (
22 $KindN:ident,
23 $ApplyN:ident,
24 $kind_string:literal,
25 ()
26 ) => {
27 #[doc = concat!(
28 "Trait for [brands][crate::brands] of [types][crate::types] of kind `",
29 $kind_string,
30 "`."
31 )]
32 pub trait $KindN {
33 type Output;
34 }
35
36 impl<Brand> Kind<()> for Brand
37 where
38 Brand: $KindN,
39 {
40 type Output = $ApplyN<Brand>;
41 }
42 };
43 (
44 $KindN:ident,
45 $ApplyN:ident,
46 $kind_string:literal,
47 ($($Generics:ident),+)
48 ) => {
49 #[doc = concat!(
50 "Trait for [brands][crate::brands] of [types][crate::types] of kind `",
51 $kind_string,
52 "`."
53 )]
54 pub trait $KindN<$($Generics),+> {
55 type Output;
56 }
57
58 impl<Brand, $($Generics),+> Kind<($($Generics,)+)> for Brand
59 where
60 Brand: $KindN<$($Generics),+>,
61 {
62 type Output = $ApplyN<Brand, $($Generics),+>;
63 }
64 };
65}
66
67#[macro_export]
80macro_rules! make_type_apply {
81 (
82 $KindN:ident,
83 $ApplyN:ident,
84 $kind_string:literal,
85 ()
86 ) => {
87 #[doc = concat!(
88 "Alias for [types][crate::types] of kind `",
89 $kind_string,
90 "`."
91 )]
92 pub type $ApplyN<Brand> = <Brand as $KindN>::Output;
93 };
94 (
95 $KindN:ident,
96 $ApplyN:ident,
97 $kind_string:literal,
98 ($($Generics:ident),+)
99 ) => {
100 #[doc = concat!(
101 "Alias for [types][crate::types] of kind `",
102 $kind_string,
103 "`."
104 )]
105 pub type $ApplyN<Brand, $($Generics),+> = <Brand as $KindN<$($Generics),+>>::Output;
106 };
107}
108
109#[macro_export]
120macro_rules! make_trait_brand {
121 (
122 $BrandN:ident,
123 $kind_string:literal,
124 ()
125 ) => {
126 #[doc = concat!(
127 "[`BrandN` trait][crate::hkt::brands] for [types][crate::types] with kind `",
128 $kind_string,
129 "`."
130 )]
131 pub trait $BrandN<Concrete>
132 where
133 Self: Kind<()>,
134 {
135 fn inject(a: Concrete) -> Apply<Self, ()>;
136 fn project(a: Apply<Self, ()>) -> Concrete;
137 }
138
139 impl<Me, Concrete> Brand<Concrete, ()> for Me
140 where
141 Me: Kind<()> + $BrandN<Concrete>,
142 {
143 fn inject(a: Concrete) -> Apply<Self, ()> {
144 <Me as $BrandN<Concrete>>::inject(a)
145 }
146
147 fn project(a: Apply<Self, ()>) -> Concrete {
148 <Me as $BrandN<Concrete>>::project(a)
149 }
150 }
151 };
152 (
153 $BrandN:ident,
154 $kind_string:literal,
155 ($($Generics:ident),+)
156 ) => {
157 #[doc = concat!(
158 "[`BrandN` trait][crate::hkt::brands] for [types][crate::types] with kind `",
159 $kind_string,
160 "`."
161 )]
162 pub trait $BrandN<Concrete, $($Generics),+>
163 where
164 Self: Kind<($($Generics,)+)>,
165 {
166 fn inject(a: Concrete) -> Apply<Self, ($($Generics,)+)>;
167 fn project(a: Apply<Self, ($($Generics,)+)>) -> Concrete;
168 }
169
170 impl<Me, Concrete, $($Generics),+> Brand<Concrete, ($($Generics,)+)> for Me
171 where
172 Me: Kind<($($Generics,)+)> + $BrandN<Concrete, $($Generics),+>,
173 {
174 fn inject(a: Concrete) -> Apply<Self, ($($Generics,)+)> {
175 <Me as $BrandN<Concrete, $($Generics),+>>::inject(a)
176 }
177
178 fn project(a: Apply<Self, ($($Generics,)+)>) -> Concrete {
179 <Me as $BrandN<Concrete, $($Generics),+>>::project(a)
180 }
181 }
182 };
183}
184
185#[macro_export]
199macro_rules! impl_brand {
200 (
201 $Brand:ident,
202 $Concrete:ident,
203 $KindN:ident,
204 $BrandN:ident,
205 ()
206 ) => {
207 #[doc = concat!(
208 "[Brand][crate::brands] for [`",
209 stringify!($Concrete),
210 "`]."
211 )]
212 pub struct $Brand;
213
214 impl $KindN for $Brand {
215 type Output = $Concrete;
216 }
217
218 impl $BrandN<$Concrete> for $Brand {
219 fn inject(a: $Concrete) -> Apply<Self, ()> {
220 a
221 }
222
223 fn project(a: Apply<Self, ()>) -> $Concrete {
224 a
225 }
226 }
227 };
228 (
229 $Brand:ident,
230 $Concrete:ident,
231 $KindN:ident,
232 $BrandN:ident,
233 ($($Generics:ident),+)
234 ) => {
235 #[doc = concat!(
236 "[Brand][crate::brands] for [`",
237 stringify!($Concrete),
238 "`]."
239 )]
240 pub struct $Brand;
241
242 impl<$($Generics),+> $KindN<$($Generics),+> for $Brand {
243 type Output = $Concrete<$($Generics),+>;
244 }
245
246 impl<$($Generics),+> $BrandN<$Concrete<$($Generics),+>, $($Generics,)+> for $Brand {
247 fn inject(a: $Concrete<$($Generics),+>) -> Apply<Self, ($($Generics,)+)> {
248 a
249 }
250
251 fn project(a: Apply<Self, ($($Generics,)+)>) -> $Concrete<$($Generics),+> {
252 a
253 }
254 }
255 }
256}