@@ -140,7 +140,7 @@ pub struct Adapter<'a, R, S> {
140140impl < ' a , R , S , E > From < S > for Adapter < ' a , R , S >
141141where
142142 S : Service < Request , Response = R , Error = E > ,
143- S :: Future : ' a ,
143+ S :: Future : Send + ' a ,
144144 R : IntoResponse ,
145145{
146146 fn from ( service : S ) -> Self {
@@ -154,7 +154,7 @@ where
154154impl < ' a , R , S , E > Service < LambdaEvent < LambdaRequest > > for Adapter < ' a , R , S >
155155where
156156 S : Service < Request , Response = R , Error = E > ,
157- S :: Future : ' a ,
157+ S :: Future : Send + ' a ,
158158 R : IntoResponse ,
159159{
160160 type Response = LambdaResponse ;
@@ -182,9 +182,65 @@ where
182182pub async fn run < ' a , R , S , E > ( handler : S ) -> Result < ( ) , Error >
183183where
184184 S : Service < Request , Response = R , Error = E > ,
185- S :: Future : ' a ,
185+ S :: Future : Send + ' a ,
186186 R : IntoResponse ,
187187 E : std:: fmt:: Debug + std:: fmt:: Display ,
188188{
189189 lambda_runtime:: run ( Adapter :: from ( handler) ) . await
190190}
191+
192+ #[ cfg( test) ]
193+ mod test_adapter {
194+ use std:: task:: { Context , Poll } ;
195+
196+ use crate :: {
197+ http:: { Response , StatusCode } ,
198+ lambda_runtime:: LambdaEvent ,
199+ request:: LambdaRequest ,
200+ response:: LambdaResponse ,
201+ tower:: { util:: BoxService , Service , ServiceBuilder , ServiceExt } ,
202+ Adapter , Body , Request ,
203+ } ;
204+
205+ // A middleware that logs requests before forwarding them to another service
206+ struct LogService < S > {
207+ inner : S ,
208+ }
209+
210+ impl < S > Service < LambdaEvent < LambdaRequest > > for LogService < S >
211+ where
212+ S : Service < LambdaEvent < LambdaRequest > > ,
213+ {
214+ type Response = S :: Response ;
215+ type Error = S :: Error ;
216+ type Future = S :: Future ;
217+
218+ fn poll_ready ( & mut self , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , Self :: Error > > {
219+ self . inner . poll_ready ( cx)
220+ }
221+
222+ fn call ( & mut self , event : LambdaEvent < LambdaRequest > ) -> Self :: Future {
223+ // Log the request
224+ println ! ( "Lambda event: {:#?}" , event) ;
225+
226+ self . inner . call ( event)
227+ }
228+ }
229+
230+ /// This tests that `Adapter` can be used in a `tower::Service` where the user
231+ /// may require additional middleware between `lambda_runtime::run` and where
232+ /// the `LambdaEvent` is converted into a `Request`.
233+ #[ test]
234+ fn adapter_is_boxable ( ) {
235+ let _service: BoxService < LambdaEvent < LambdaRequest > , LambdaResponse , http:: Error > = ServiceBuilder :: new ( )
236+ . layer_fn ( |service| {
237+ // This could be any middleware that logs, inspects, or manipulates
238+ // the `LambdaEvent` before it's converted to a `Request` by `Adapter`.
239+
240+ LogService { inner : service }
241+ } )
242+ . layer_fn ( Adapter :: from)
243+ . service_fn ( |_event : Request | async move { Response :: builder ( ) . status ( StatusCode :: OK ) . body ( Body :: Empty ) } )
244+ . boxed ( ) ;
245+ }
246+ }
0 commit comments