fp_library/
macros.rs

1//! Macros for generating higher-kinded type traits and implementations.
2//!
3//! These macros provide a systematic way to generate traits for different kind arities,
4//! allowing the library to work with types of varying complexity from concrete types
5//! (kind `*`) to type constructors (kinds `* -> *`, `* -> * -> *`, etc.).
6
7/// Generates a [`Kind` trait][crate::hkt::kinds] of a specific arity.
8///
9/// This macro creates traits that represent type-level applications for different kind arities.
10/// Each generated trait has an `Output` associated type that represents the concrete type
11/// produced when the brand is applied to the appropriate type parameters.
12///
13/// # Parameters
14/// * `kind_trait_name`: Trait name (e.g., `Kind0L1T`).
15/// * `lifetimes`: Tuple of lifetime parameters (e.g., `('a, 'b)`).
16/// * `types`: Tuple of type parameters (e.g., `(A, B)`).
17/// * `kind_signature`: Kind signature (e.g., `"* -> *"`).
18#[macro_export]
19macro_rules! make_trait_kind {
20	(
21		$kind_trait_name:ident,
22		$lifetimes:tt,
23		$types:tt,
24		$kind_signature:literal
25	) => {
26		make_trait_kind!(
27			@impl $kind_trait_name,
28			$lifetimes,
29			$types,
30			$kind_signature
31		);
32	};
33
34	(
35		@impl $kind_trait_name:ident,
36		(),
37		(),
38		$kind_signature:literal
39	) => {
40		#[doc = concat!(
41			"Trait for [brands][crate::brands] of [types][crate::types] of kind `",
42			$kind_signature,
43			"`."
44		)]
45		pub trait $kind_trait_name {
46			type Output;
47		}
48	};
49
50	(
51		@impl $kind_trait_name:ident,
52		($($lifetimes:lifetime),+),
53		(),
54		$kind_signature:literal
55	) => {
56		#[doc = concat!(
57			"Trait for [brands][crate::brands] of [types][crate::types] of kind `",
58			$kind_signature,
59			"`."
60		)]
61		pub trait $kind_trait_name {
62			type Output<$($lifetimes),*>;
63		}
64	};
65
66	(
67		@impl $kind_trait_name:ident,
68		(),
69		($($types:ident),+),
70		$kind_signature:literal
71	) => {
72		#[doc = concat!(
73			"Trait for [brands][crate::brands] of [types][crate::types] of kind `",
74			$kind_signature,
75			"`."
76		)]
77		pub trait $kind_trait_name {
78			type Output<$($types),*>;
79		}
80	};
81
82	(
83		@impl $kind_trait_name:ident,
84		($($lifetimes:lifetime),+),
85		($($types:ident),+),
86		$kind_signature:literal
87	) => {
88		#[doc = concat!(
89			"Trait for [brands][crate::brands] of [types][crate::types] of kind `",
90			$kind_signature,
91			"`."
92		)]
93		pub trait $kind_trait_name {
94			type Output<$($lifetimes),*, $($types),*>;
95		}
96	};
97}
98
99/// Generates an [`Apply` type alias][crate::hkt::apply] of a specific arity.
100///
101/// This macro creates type aliases that simplify the usage of kind traits by providing
102/// a more convenient syntax for type applications. These aliases are used throughout
103/// the library to make type signatures more readable.
104///
105/// # Parameters
106/// * `apply_alias_name`: Type alias name (e.g., `Apply0L1T`).
107/// * `kind_trait_name`: Trait name (e.g., `Kind0L1T`).
108/// * `lifetimes`: Tuple of lifetime parameters (e.g., `('a, 'b)`).
109/// * `types`: Tuple of type parameters (e.g., `(A, B)`).
110/// * `kind_signature`: Kind signature (e.g., `"* -> *"`).
111#[macro_export]
112macro_rules! make_type_apply {
113	(
114		$apply_alias_name:ident,
115		$kind_trait_name:ident,
116		$lifetimes:tt,
117		$types:tt,
118		$kind_signature:literal
119	) => {
120		make_type_apply!(
121			@impl $apply_alias_name,
122			$kind_trait_name,
123			$lifetimes,
124			$types,
125			$kind_signature
126		);
127	};
128
129	(
130		@impl $apply_alias_name:ident,
131		$kind_trait_name:ident,
132		(),
133		(),
134		$kind_signature:literal
135	) => {
136		#[doc = concat!(
137			"Alias for [types][crate::types] of kind `",
138			$kind_signature,
139			"`."
140		)]
141		pub type $apply_alias_name<Brand> = <Brand as $kind_trait_name>::Output;
142	};
143
144	(
145		@impl $apply_alias_name:ident,
146		$kind_trait_name:ident,
147		($($lifetimes:lifetime),+),
148		(),
149		$kind_signature:literal
150	) => {
151		#[doc = concat!(
152			"Alias for [types][crate::types] of kind `",
153			$kind_signature,
154			"`."
155		)]
156		pub type $apply_alias_name<$($lifetimes),*, Brand> = <Brand as $kind_trait_name>::Output<$($lifetimes),*>;
157	};
158
159	(
160		@impl $apply_alias_name:ident,
161		$kind_trait_name:ident,
162		(),
163		($($types:ident),+),
164		$kind_signature:literal
165	) => {
166		#[doc = concat!(
167			"Alias for [types][crate::types] of kind `",
168			$kind_signature,
169			"`."
170		)]
171		pub type $apply_alias_name<Brand $(, $types)*> = <Brand as $kind_trait_name>::Output<$($types),*>;
172	};
173
174	(
175		@impl $apply_alias_name:ident,
176		$kind_trait_name:ident,
177		($($lifetimes:lifetime),+),
178		($($types:ident),+),
179		$kind_signature:literal
180	) => {
181		#[doc = concat!(
182			"Alias for [types][crate::types] of kind `",
183			$kind_signature,
184			"`."
185		)]
186		pub type $apply_alias_name<$($lifetimes),*, Brand $(, $types)*> = <Brand as $kind_trait_name>::Output<$($lifetimes),* $(, $types)*>;
187	};
188}