higher_kinded_types/
hkt_macro.rs

1crate::utils::cfg_match! {
2    feature = "fn_traits" => (
3        dispatch! {$
4            fn_traits = true
5        }
6    );
7    _ => (
8        dispatch! {$
9            fn_traits = false
10        }
11    );
12}
13
14macro_rules! dispatch {($_:tt
15    fn_traits =
16        $(true $($if_cfg_fn_traits:tt)?)?
17        $(false $($if_not_cfg_fn_traits:tt)?)?
18) => (
19    /// Produce <code>impl [ForLt]</code>[^auto] types _on demand_.
20    ///
21    /// [ForLt]: trait@crate::ForLt
22    /// [^auto]: `+ Send + Sync + Unpin`
23    ///
24    /// ### Syntax
25    ///
26    ///   - #### Full syntax
27    ///
28    ///     ```rust
29    ///     # use ::higher_kinded_types::ForLt;
30    ///     # mod some { pub use ::std::borrow::Cow as Arbitrary; }
31    ///     # use str as Type; let _:
32    ///     ForLt!(<'r> = some::Arbitrary<'r, Type>)
33    ///     # ;
34    ///     ```
35    ///
36    ///   - #### Shorthand syntax
37    ///
38    ///     You can use the anonymous/elided `'_` lifetime (or even implicitly
39    ///     elided if behind `&`) in which case you skip the `<'lt> =` part, and
40    ///     just write:
41    ///
42    ///     ```rust
43    ///     # use ::higher_kinded_types::ForLt;
44    ///     # mod some { pub use ::std::borrow::Cow as Arbitrary; }
45    ///     # use str as Type; let _:
46    ///     ForLt!(some::Arbitrary<'_, Type>)
47    ///     # ;
48    ///     ```
49    ///
50    /// ### Examples
51    ///
52    /// ```rust
53    /// use ::higher_kinded_types::ForLt;
54    ///
55    /// type A = ForLt!(<'r> = &'r str);
56    /// // the following two definitions are equivalent to A (syntax sugar).
57    /// type B = ForLt!(&'_ str);
58    /// type C = ForLt!(&str);
59    ///
60    /// //     Let `'r` be `'static`, this results in:
61    /// //                      |
62    /// //                      vvvvvvv
63    /// let a: <A as ForLt>::Of<'static> = "a";
64    /// //     ^^^^^^^^^^^^^^^^^^^^^^^^^
65    /// //          `&'static str` !
66    /// //     vvvvvvvvvvvvvvvvvvvvvvvvv
67    /// let b: <B as ForLt>::Of<'static> = "b";
68    /// let c: <C as ForLt>::Of<'static> = "c";
69    /// ```
70    #[macro_export]
71    macro_rules! ForLt {
72        (
73            // Named lifetime case: e.g. `ForLt!(<'r> = &'r str)`.
74            <$lt:lifetime> = $T:ty $_(,)?
75        ) => (
76            $($($if_cfg_fn_traits)?
77                $_ crate::ඞ::ForLt<
78                    for<$lt> fn($_ crate::ඞ::__<$lt>) -> $T
79                >
80            )?
81            $($($if_not_cfg_fn_traits)?
82                $_ crate::ඞ::ForLt<
83                    dyn for<$lt> $_ crate::ඞ::WithLifetime<$lt, T = $T>,
84                >
85            )?
86        );
87
88        (
89            // default case: as if we had `ForLt!(<'_> = $($input)*)`.
90            // For instance: `ForLt!(&str)` or `ForLt!(&'_ str)`.
91            $_($shorthand_syntax:tt)*
92        ) => (
93            $($($if_cfg_fn_traits)?
94                $_ crate::ඞ::ForLt<
95                    fn($_ crate::ඞ::r#for<'_>) -> $_($shorthand_syntax)*
96                >
97            )?
98            $($($if_not_cfg_fn_traits)?
99                $_ crate::ForLt! {
100                    <'ඞ /* ' */> = $_ crate::ඞForLt_munch! {
101                        [output: ]
102                        [input: $_($shorthand_syntax)*]
103                        [mode: default]
104                    }
105                }
106            )?
107        );
108    }
109)}
110use dispatch;