1#[macro_export]
5macro_rules! make_trait_kind {
6 (
7 $KindN:ident,
9 $ApplyN:ident,
11 $kind_string:literal,
13 ($($Generics:ident),+)
15 ) => {
16 #[doc = concat!(
17 "Trait for [brands][crate::brands] of [types][crate::types] of kind `",
18 $kind_string,
19 "`."
20 )]
21 pub trait $KindN<$($Generics),+> {
22 type Output;
23 }
24
25 impl<Brand, $($Generics),+> Kind<($($Generics,)+)> for Brand
26 where
27 Brand: $KindN<$($Generics),+>,
28 {
29 type Output = $ApplyN<Brand, $($Generics),+>;
30 }
31 };
32}
33
34#[macro_export]
36macro_rules! make_type_apply {
37 (
38 $KindN:ident,
40 $ApplyN:ident,
42 $kind_string:literal,
44 ($($Generics:ident),+)
46 ) => {
47 #[doc = concat!(
48 "Alias for [types][crate::types] of kind `",
49 $kind_string,
50 "`."
51 )]
52 pub type $ApplyN<Brand, $($Generics),+> = <Brand as $KindN<$($Generics),+>>::Output;
53 };
54}
55
56#[macro_export]
58macro_rules! make_trait_brand {
59 (
60 $BrandN:ident,
62 $kind_string:literal,
64 ($($Generics:ident),+)
66 ) => {
67 #[doc = concat!(
68 "[`BrandN` trait][crate::hkt::brands] for [types][crate::types] with kind `",
69 $kind_string,
70 "`."
71 )]
72 pub trait $BrandN<Concrete, $($Generics),+>
73 where
74 Self: Kind<($($Generics,)+)>,
75 {
76 fn inject(a: Concrete) -> Apply<Self, ($($Generics,)+)>;
77 fn project(a: Apply<Self, ($($Generics,)+)>) -> Concrete;
78 }
79
80 impl<Me, Concrete, $($Generics),+> Brand<Concrete, ($($Generics,)+)> for Me
81 where
82 Me: Kind<($($Generics,)+)> + $BrandN<Concrete, $($Generics),+>,
83 {
84 fn inject(a: Concrete) -> Apply<Self, ($($Generics,)+)> {
85 <Me as $BrandN<Concrete, $($Generics),+>>::inject(a)
86 }
87
88 fn project(a: Apply<Self, ($($Generics,)+)>) -> Concrete {
89 <Me as $BrandN<Concrete, $($Generics),+>>::project(a)
90 }
91 }
92 };
93}
94
95#[macro_export]
97macro_rules! impl_brand {
98 (
99 $Brand:ident,
101 $Concrete:ident,
103 $KindN:ident,
105 $BrandN:ident,
107 ($($Generics:ident),+)
109 ) => {
110 #[doc = concat!(
111 "[Brand][crate::brands] for [`",
112 stringify!($Concrete),
113 "`]."
114 )]
115 pub struct $Brand;
116
117 impl<$($Generics),+> $KindN<$($Generics),+> for $Brand {
118 type Output = $Concrete<$($Generics),+>;
119 }
120
121 impl<$($Generics),+> $BrandN<$Concrete<$($Generics),+>, $($Generics,)+> for $Brand {
122 fn inject(a: $Concrete<$($Generics),+>) -> Apply<Self, ($($Generics,)+)> {
123 a
124 }
125
126 fn project(a: Apply<Self, ($($Generics,)+)>) -> $Concrete<$($Generics),+> {
127 a
128 }
129 }
130 }
131}