@@ -2,6 +2,7 @@ use std::string::String as StdString;
22
33use crate :: error:: Result ;
44use crate :: private:: Sealed ;
5+ use crate :: types:: MaybeSend ;
56use crate :: value:: { FromLua , FromLuaMulti , IntoLua , IntoLuaMulti } ;
67
78#[ cfg( feature = "async" ) ]
@@ -76,3 +77,94 @@ pub trait ObjectLike: Sealed {
7677 /// This might invoke the `__tostring` metamethod.
7778 fn to_string ( & self ) -> Result < StdString > ;
7879}
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