@@ -2,6 +2,7 @@ use std::string::String as StdString;
2
2
3
3
use crate :: error:: Result ;
4
4
use crate :: private:: Sealed ;
5
+ use crate :: types:: MaybeSend ;
5
6
use crate :: value:: { FromLua , FromLuaMulti , IntoLua , IntoLuaMulti } ;
6
7
7
8
#[ cfg( feature = "async" ) ]
@@ -76,3 +77,94 @@ pub trait ObjectLike: Sealed {
76
77
/// This might invoke the `__tostring` metamethod.
77
78
fn to_string ( & self ) -> Result < StdString > ;
78
79
}
80
+
81
+ /// A trait for types that can be used as Lua functions.
82
+ pub trait LuaNativeFn < A : FromLuaMulti > {
83
+ type Output : IntoLuaMulti ;
84
+
85
+ fn call ( & self , args : A ) -> Self :: Output ;
86
+ }
87
+
88
+ /// A trait for types with mutable state that can be used as Lua functions.
89
+ pub trait LuaNativeFnMut < A : FromLuaMulti > {
90
+ type Output : IntoLuaMulti ;
91
+
92
+ fn call ( & mut self , args : A ) -> Self :: Output ;
93
+ }
94
+
95
+ /// A trait for types that returns a future and can be used as Lua functions.
96
+ #[ cfg( feature = "async" ) ]
97
+ pub trait LuaNativeAsyncFn < A : FromLuaMulti > {
98
+ type Output : IntoLuaMulti ;
99
+
100
+ fn call ( & self , args : A ) -> impl Future < Output = Self :: Output > + MaybeSend + ' static ;
101
+ }
102
+
103
+ macro_rules! impl_lua_native_fn {
104
+ ( $( $A: ident) ,* ) => {
105
+ impl <FN , $( $A, ) * R > LuaNativeFn <( $( $A, ) * ) > for FN
106
+ where
107
+ FN : Fn ( $( $A, ) * ) -> R + MaybeSend + ' static ,
108
+ ( $( $A, ) * ) : FromLuaMulti ,
109
+ R : IntoLuaMulti ,
110
+ {
111
+ type Output = R ;
112
+
113
+ #[ allow( non_snake_case) ]
114
+ fn call( & self , args: ( $( $A, ) * ) ) -> Self :: Output {
115
+ let ( $( $A, ) * ) = args;
116
+ self ( $( $A, ) * )
117
+ }
118
+ }
119
+
120
+ impl <FN , $( $A, ) * R > LuaNativeFnMut <( $( $A, ) * ) > for FN
121
+ where
122
+ FN : FnMut ( $( $A, ) * ) -> R + MaybeSend + ' static ,
123
+ ( $( $A, ) * ) : FromLuaMulti ,
124
+ R : IntoLuaMulti ,
125
+ {
126
+ type Output = R ;
127
+
128
+ #[ allow( non_snake_case) ]
129
+ fn call( & mut self , args: ( $( $A, ) * ) ) -> Self :: Output {
130
+ let ( $( $A, ) * ) = args;
131
+ self ( $( $A, ) * )
132
+ }
133
+ }
134
+
135
+ #[ cfg( feature = "async" ) ]
136
+ impl <FN , $( $A, ) * Fut , R > LuaNativeAsyncFn <( $( $A, ) * ) > for FN
137
+ where
138
+ FN : Fn ( $( $A, ) * ) -> Fut + MaybeSend + ' static ,
139
+ ( $( $A, ) * ) : FromLuaMulti ,
140
+ Fut : Future <Output = R > + MaybeSend + ' static ,
141
+ R : IntoLuaMulti ,
142
+ {
143
+ type Output = R ;
144
+
145
+ #[ allow( non_snake_case) ]
146
+ fn call( & self , args: ( $( $A, ) * ) ) -> impl Future <Output = Self :: Output > + MaybeSend + ' static {
147
+ let ( $( $A, ) * ) = args;
148
+ self ( $( $A, ) * )
149
+ }
150
+ }
151
+ } ;
152
+ }
153
+
154
+ impl_lua_native_fn ! ( ) ;
155
+ impl_lua_native_fn ! ( A ) ;
156
+ impl_lua_native_fn ! ( A , B ) ;
157
+ impl_lua_native_fn ! ( A , B , C ) ;
158
+ impl_lua_native_fn ! ( A , B , C , D ) ;
159
+ impl_lua_native_fn ! ( A , B , C , D , E ) ;
160
+ impl_lua_native_fn ! ( A , B , C , D , E , F ) ;
161
+ impl_lua_native_fn ! ( A , B , C , D , E , F , G ) ;
162
+ impl_lua_native_fn ! ( A , B , C , D , E , F , G , H ) ;
163
+ impl_lua_native_fn ! ( A , B , C , D , E , F , G , H , I ) ;
164
+ impl_lua_native_fn ! ( A , B , C , D , E , F , G , H , I , J ) ;
165
+ impl_lua_native_fn ! ( A , B , C , D , E , F , G , H , I , J , K ) ;
166
+ impl_lua_native_fn ! ( A , B , C , D , E , F , G , H , I , J , K , L ) ;
167
+ impl_lua_native_fn ! ( A , B , C , D , E , F , G , H , I , J , K , L , M ) ;
168
+ impl_lua_native_fn ! ( A , B , C , D , E , F , G , H , I , J , K , L , M , N ) ;
169
+ impl_lua_native_fn ! ( A , B , C , D , E , F , G , H , I , J , K , L , M , N , O ) ;
170
+ impl_lua_native_fn ! ( A , B , C , D , E , F , G , H , I , J , K , L , M , N , O , P ) ;
0 commit comments