typewit/macros/
inj_type_fn_macro.rs

1
2/// Declares an
3/// [injective type-level function](crate::type_fn::InjTypeFn)
4/// 
5/// This macro takes in the exact same syntax as the [`type_fn`] macro.
6/// 
7/// This macro generates the same items as the `type_fn` macro,
8/// in addition to implementing [`RevTypeFn`], 
9/// so that the function implements [`InjTypeFn`].
10/// 
11/// 
12/// # Example
13/// 
14/// This macro is also demonstrated in 
15/// `TypeNe::{`[`map`]`, `[`project`]`, `[`unmap`]`, `[`unproject`]`}`.
16/// 
17/// [`map`]: crate::TypeNe::map
18/// [`project`]: crate::TypeNe::project
19/// [`unmap`]: crate::TypeNe::unmap
20/// [`unproject`]: crate::TypeNe::unproject
21/// 
22/// ### Basic
23/// 
24/// ```rust
25/// use typewit::{CallFn, UncallFn, inj_type_fn};
26/// 
27/// // Calls the `ToSigned` function with `u64` as the argument.
28/// let _: CallFn<ToSigned, u64> = 3i64;
29/// 
30/// // Gets the argument of the `ToSigned` function from the `i8` return value.
31/// let _: UncallFn<ToSigned, i8> = 5u8;
32/// 
33/// inj_type_fn!{
34///     struct ToSigned;
35/// 
36///     impl u128 => i128;
37///     impl u64 => i64;
38///     impl u32 => i32;
39///     impl u16 => i16;
40///     impl u8 => i8;
41/// }
42/// ```
43/// 
44/// <details>
45/// <summary>
46/// <p>
47/// 
48/// the above `inj_type_fn` macro invocation roughly expands to this code
49/// </p>
50/// </summary>
51///
52/// ```rust
53/// struct ToSigned;
54/// 
55/// impl ToSigned {
56///     const NEW: Self = Self;
57/// }
58/// 
59/// impl ::typewit::TypeFn<u128> for ToSigned {
60///     type Output = i128;
61/// }
62/// 
63/// impl ::typewit::RevTypeFn<i128> for ToSigned {
64///     type Arg = u128;
65/// }
66/// 
67/// impl ::typewit::TypeFn<u64> for ToSigned {
68///     type Output = i64;
69/// }
70/// 
71/// impl ::typewit::RevTypeFn<i64> for ToSigned {
72///     type Arg = u64;
73/// }
74/// 
75/// impl ::typewit::TypeFn<u32> for ToSigned {
76///     type Output = i32;
77/// }
78/// 
79/// impl ::typewit::RevTypeFn<i32> for ToSigned {
80///     type Arg = u32;
81/// }
82/// 
83/// impl ::typewit::TypeFn<u16> for ToSigned {
84///     type Output = i16;
85/// }
86/// 
87/// impl ::typewit::RevTypeFn<i16> for ToSigned {
88///     type Arg = u16;
89/// }
90/// 
91/// impl ::typewit::TypeFn<u8> for ToSigned {
92///     type Output = i8;
93/// }
94/// 
95/// impl ::typewit::RevTypeFn<i8> for ToSigned {
96///     type Arg = u8;
97/// }
98/// ```
99/// </details>
100/// 
101/// [`type_fn`]: macro@crate::type_fn
102/// [`TypeFn`]: crate::type_fn::TypeFn
103/// [`InjTypeFn`]: crate::type_fn::InjTypeFn
104/// [`RevTypeFn`]: crate::type_fn::RevTypeFn
105#[macro_export]
106macro_rules! inj_type_fn {
107    ($($args:tt)*) => {
108        $crate::__type_fn!{
109            __tyfn_injtypefn_impl
110            $($args)*
111        }
112    }
113}
114
115
116#[doc(hidden)]
117#[macro_export]
118macro_rules! __tyfn_injtypefn_impl {
119    (
120        (
121            $(#[$attrs:meta])*
122            $impl:ident[$(($($fn_gen_param:tt)*))*] $ty_arg:ty => $ret_ty:ty
123            where[ $($where_preds:tt)* ] 
124        )
125
126        $function_name:ident
127
128        [$(($capt_gen_args:tt $($rem_0:tt)*))*]
129        [
130            $(($capt_lt:lifetime $($capt_lt_rem:tt)*))*
131            $(($capt_tcp:ident $($capt_tcp_rem:tt)*))*
132        ]
133        where [$($capt_where:tt)*]
134        
135    ) => {
136        $crate::__impl_with_span! {
137            $ty_arg // span
138            ( $(#[$attrs])* #[allow(unused_parens)] )
139            (
140                <
141                    $($capt_lt $($capt_lt_rem)*,)*
142                    $($($fn_gen_param)*,)*
143                    $($capt_tcp $($capt_tcp_rem)*,)*
144                > $crate::TypeFn<$ty_arg> 
145            )
146            // for
147            ( $function_name<$($capt_gen_args),*> )
148            (
149                where
150                    $($capt_where)*
151                    $($where_preds)*
152            )
153            (
154                type Output = $ret_ty;
155
156                const TYPE_FN_ASSERTS: () = { let _: $crate::CallInjFn<Self, $ty_arg>; };
157            )
158        }
159
160        $crate::__impl_with_span! {
161            $ret_ty // span
162            ( $(#[$attrs])* #[allow(unused_parens)] )
163            (
164                <
165                    $($capt_lt $($capt_lt_rem)*,)*
166                    $($($fn_gen_param)*,)*
167                    $($capt_tcp $($capt_tcp_rem)*,)*
168                > $crate::type_fn::RevTypeFn<$ret_ty> 
169            )
170            // for
171            ( $function_name<$($capt_gen_args),*> )
172            (
173                where
174                    $($capt_where)*
175                    $($where_preds)*
176            )
177            (
178                type Arg = $ty_arg;
179            )
180        }
181    };
182}