1#![no_std]
2
3mod traits;
15pub use traits::*;
16
17pub mod accept_anything;
18pub mod chain;
19
20pub mod argument;
21pub use argument::{ArgumentOfType, ArgumentType, ArgumentTypes, ArgumentsOfTypes};
22
23mod maybe_handle_event;
24pub use maybe_handle_event::*;
25
26#[cfg(feature = "gat")]
27pub mod gat;
28
29mod sealed {
30 pub trait Sealed {}
31}
32
33mod private {
34 #[derive(Debug, Clone, Copy)]
35 pub struct HkFn<F>(pub(crate) F);
36}
37
38#[cfg(feature = "impl_with_macro_rules")]
39mod imp {
40 mod macros;
41 macros::impl_with_macro_rules!(a1: A1, a2: A2, a3: A3, a4: A4);
42}
43
44#[cfg(not(feature = "impl_with_macro_rules"))]
45mod imp;
46
47pub use imp::*;
48
49#[macro_export]
59macro_rules! ArgumentType {
60 (&mut $t:ty) => { $crate::argument::ByMut<$t> };
61 (& $t:ty) => { $crate::argument::ByRef<$t> };
62 ( $t:ty) => { $crate::argument::Value<$t> };
63}
64
65#[macro_export]
66macro_rules! ArgumentTypes {
67 () => {
68 ()
69 };
70 (@$resolved:tt) => {
71 $resolved
72 };
73 ($(@($($resolved:tt)*))? &mut $t:ty $(, $($rest:tt)*)? ) => {
74 $crate::ArgumentTypes! { @($($($resolved)*)? $crate::argument::ByMut<$t>,) $($($rest)*)? }
75 };
76 ($(@($($resolved:tt)*))? & $t:ty $(, $($rest:tt)*)? ) => {
77 $crate::ArgumentTypes! { @($($($resolved)*)? $crate::argument::ByRef<$t>,) $($($rest)*)? }
78 };
79 ($(@($($resolved:tt)*))? $t:ty $(, $($rest:tt)*)? ) => {
80 $crate::ArgumentTypes! { @($($($resolved)*)? $crate::argument::Value<$t>,) $($($rest)*)? }
81 };
82}
83
84#[cfg(test)]
85mod tests {
86 use crate::prelude::*;
87
88 #[test]
89 fn test_callable_ref() {
90 fn asserts<T>(t: T) -> T
91 where
92 T: for<'i> CallableOne<&'i usize, Output = usize>,
93 {
94 t
95 }
96
97 let cbk = asserts(crate::r#ref(Clone::clone));
98 assert_eq!(cbk.emit(&0), 0);
99 assert_eq!(cbk.provide_last_argument_refed(8).call_fn(()), 8);
100 }
101
102 #[test]
103 fn mods() {
104 let _: fn() = callable(|| {});
105
106 let _: fn(()) = crate::value(|()| {});
107 let _: callable![fn(&())] = crate::r#ref(|&()| {});
108 let _: callable![fn(&mut ())] = crate::r#mut(|&mut ()| {});
109
110 let _: fn((), ()) = crate::value::value(|(), ()| {});
111 let _: crate::value::HkFn<fn((), &())> = crate::value::r#ref(|(), &()| {});
112 }
113}
114
115mod fn_pointer_fn {
116 #[allow(non_snake_case)]
117 pub fn FnPointer<Out>(f: fn() -> Out) -> fn() -> Out {
118 f
119 }
120}
121pub use fn_pointer_fn::FnPointer;
122pub type FnPointer<Out> = fn() -> Out;
123
124pub use fn_pointer_fn::FnPointer as callable;
125
126pub mod prelude {
127 pub use crate::{ArgumentTypes, Callable, CallableOne, CallableWithFixedArguments, IsCallable};
128
129 pub use crate as callable;
130 pub use crate::callable;
131}
132
133#[doc(hidden)]
134#[macro_export]
135macro_rules! __expand_or {
136 ([ ] $($b:tt)*) => { $($b)* };
137 ([$($a:tt)+] $($b:tt)*) => { $($a)+ };
138}
139
140macro_rules! impl_callable_parse_input {
141 ($dollar:tt $([$($match:tt)*][$($clone:tt)*] => $output_path:ident $output_input:tt )*) => {
142 #[macro_export]
143 macro_rules! __callable_parse_input {
144 ([| $dollar($other:tt)*] $_clone:tt $path:tt $input:tt ) => {
146 $crate::__callable_input_resolved! { [$path $input] $dollar($other)* }
147 };
148 $(
149 ( [$($match)* , $dollar($_rest:tt)*]
150 [$($clone)* , $dollar($ rest:tt)*]
151 {$dollar($paths:ident)*}
152 {$dollar($inputs:tt )*}
153 ) => {
154 $crate::__callable_parse_input! {
155 [$dollar($_rest)*]
156 [$dollar($ rest)*]
157 {$dollar($paths )* $output_path }
158 {$dollar($inputs)* $output_input}
159 }
160 };
161 ( [$($match)* | $dollar($_rest:tt)*]
162 [$($clone)* | $dollar($ rest:tt)*]
163 {$dollar($paths:ident)*}
164 {$dollar($inputs:tt )*}
165 ) => {
166 $crate::__callable_input_resolved! { [
167 {$dollar($paths )* $output_path }
168 {$dollar($inputs)* $output_input}
169 ] $dollar($rest)* }
170 };
171 )*
172 }
173 };
174}
175
176impl_callable_parse_input! { $
177 [& mut $_input:pat_param][$r:tt $m:tt $ input:pat_param] => r#mut[$r $m $input]
179 [& mut $($_input:ident)+ : $_input_ty:ty][$r:tt $m:tt $($ input:ident)+ : $ input_ty:ty] => r#mut[$r $m $($input)+ : $input_ty]
181 [& mut $_input:tt : $_input_ty:ty][$r:tt $m:tt $ input:tt : $ input_ty:ty]=> r#mut [$r $m $input : $input_ty]
183 [ $($_input:ident)+ : &mut $_input_ty:ty][ $($ input:ident)+ : $r:tt $m:tt $ input_ty:ty]=> r#mut [$($input)+ : $r $m $input_ty]
185 [ $_input:tt : &mut $_input_ty:ty , $($_rest:tt)*][ $ input:tt : &mut $ input_ty:ty , $($ rest:tt)*]=> r#mut[$input : &mut $input_ty]
187
188 [& $_input:pat_param][$r:tt $input:pat_param] => r#ref[$r $input]
190 [& $($_input:ident)+ : $_input_ty:ty][$r:tt $($input:ident)+ : $input_ty:ty] => r#ref[$r $($input)+ : $input_ty]
192 [& $_input:tt : $_input_ty:ty][$r:tt $input:tt : $input_ty:ty] => r#ref[$r $input : $input_ty]
194 [$($_input:ident)+ : & $_input_ty:ty ][$($input:ident)+ : $r:tt $input_ty:ty ] => r#ref[$($input)+ : $r $input_ty]
196 [$_input:tt : & $_input_ty:ty ][$input:tt : $r:tt $input_ty:ty ] => r#ref[$input : $r $input_ty]
198
199 [$_input:pat_param][$input:pat_param] => value[$input]
201 [$($_input:ident)+ : $_input_ty:ty][$($input:ident)+ : $input_ty:ty] => value[$($input)+ : $input_ty]
203 [$_input:tt : $_input_ty:ty][$input:tt : $input_ty:ty] => value[$input : $input_ty]
205}
206
207#[macro_export]
213macro_rules! callable {
214 (|| $($rest:tt)*) => {
215 $crate::__callable_input_resolved! { [{} {}] $($rest)* }
216 };
217 (| $($rest:tt)* ) => {
218 $crate::__callable_parse_input! { [$($rest)*][$($rest)*]{}{} }
219 };
220 (fn($($args:tt)*) $(-> $output:ty)?) => {
221 $crate::__fn_pointer! { [$($args)*]{}{}{$($output)?} }
222 };
223}
224
225#[doc(hidden)]
226#[macro_export]
227macro_rules! __fn_pointer {
228 ([ ]{$($path:ident)*}{$($generics:tt)*}{$output_ty:ty} ) => {
229 $crate $(:: $path)* ::FnPointer::<$($generics)* $output_ty>
230 };
231 ([ ]{$($path:ident)*}{$($generics:tt)*}{ } ) => {
232 $crate $(:: $path)* ::FnPointer::<$($generics)* () >
233 };
234 ([&mut $t:ty $(, $($rest:tt)*)?]{$($path:ident)*}{$($generics:tt)*} $output_ty:tt ) => {
235 $crate::__fn_pointer! { [$($($rest)*)?]{$($path)* r#mut}{$($generics)* $t,} $output_ty }
236 };
237 ([& $t:ty $(, $($rest:tt)*)?]{$($path:ident)*}{$($generics:tt)*} $output_ty:tt ) => {
238 $crate::__fn_pointer! { [$($($rest)*)?]{$($path)* r#ref}{$($generics)* $t,} $output_ty }
239 };
240 ([ $t:ty $(, $($rest:tt)*)?]{$($path:ident)*}{$($generics:tt)*} $output_ty:tt ) => {
241 $crate::__fn_pointer! { [$($($rest)*)?]{$($path)* value}{$($generics)* $t,} $output_ty }
242 };
243}
244
245#[doc(hidden)]
246#[macro_export]
247macro_rules! __callable_input_resolved {
248 ($input:tt $body:expr $(, $($rest:tt)*)?) => {
250 $crate::__callable_all_resolved! { $input [ ] [ $body ] $($($rest)*)? }
251 };
252 ($input:tt { $($body:tt)* } $(, $($rest:tt)*)?) => {
254 $crate::__callable_all_resolved! { $input [ ] [{$($body)*}] $($($rest)*)? }
255 };
256 ($input:tt -> $output:ty { $($body:tt)* } $(, $($rest:tt)*)?) => {
258 $crate::__callable_all_resolved! { $input [$output] [{$($body)*}] $($($rest)*)? }
259 };
260}
261
262#[doc(hidden)]
263#[macro_export]
264macro_rules! __callable_all_resolved {
265 ([{$($method_path:tt)*}{$([$($input:tt)*])*}][$($output:ty)?][$($body:tt)*]) => {
267 $crate $(::$method_path)* ::FnPointer (
268 |$($($input)*),* | $(-> $output)? $($body)*
269 )
270 };
271 ([{$($method_path:tt)*}{$([$($input:tt)*])*}][$($output:ty)?][$($body:tt)*] $state:ident $(= $state_expr:expr)? $(,)?) => {
273 $crate $(::$method_path)* ::r#ref::provide_last_argument (
274 |$($($input)* ,)* $state | $(-> $output)? $($body)* ,
275 $crate::__expand_or!([$($state_expr)?] $state),
276 )
277 };
278 ([{$($method_path:tt)*}{$([$($input:tt)*])*}][$($output:ty)?][$($body:tt)*] $($state:ident $(= $state_expr:expr)?),+ $(,)?) => {
280 $crate $(::$method_path)* ::r#ref::provide_last_argument (
281 |$($($input)* ,)* ($($state,)+)| $(-> $output)? $($body)* ,
282 ($( $crate::__expand_or!([$($state_expr)?] $state) ,)+),
283 )
284 };
285}