@@ -63,7 +63,10 @@ extern crate maplit;
6363
6464pub use http:: { self , Response } ;
6565pub use lambda_runtime:: { self , Context } ;
66- use lambda_runtime:: { Error , LambdaEvent , Service } ;
66+ use lambda_runtime:: {
67+ tower:: util:: { service_fn, ServiceFn } ,
68+ Error , LambdaEvent , Service ,
69+ } ;
6770
6871mod body;
6972pub mod ext;
@@ -85,54 +88,37 @@ use std::{
8588/// Type alias for `http::Request`s with a fixed [`Body`](enum.Body.html) type
8689pub type Request = http:: Request < Body > ;
8790
88- /// Functions serving as ALB and API Gateway REST and HTTP API handlers must conform to this type.
89- ///
90- /// This can be viewed as a `lambda_runtime::Handler` constrained to `http` crate `Request` and `Response` types
91- pub trait Handler < ' a > : Sized {
92- /// The type of Error that this Handler will return
93- type Error ;
94- /// The type of Response this Handler will return
95- type Response : IntoResponse ;
96- /// The type of Future this Handler will return
97- type Fut : Future < Output = Result < Self :: Response , Self :: Error > > + ' a ;
98- /// Function used to execute handler behavior
99- fn call ( & mut self , event : Request , context : Context ) -> Self :: Fut ;
91+ /// Wraps a function that takes 2 arguments into one that only takes a [`LambdaEvent`]
92+ fn handler_wrapper < A , Fut > ( f : impl Fn ( A , Context ) -> Fut ) -> impl Fn ( LambdaEvent < A > ) -> Fut {
93+ move |req| f ( req. event , req. context )
10094}
10195
102- /// Adapts a [`Handler`](trait.Handler.html) to the `lambda_runtime::run` interface
103- pub fn handler < ' a , H : Handler < ' a > > ( handler : H ) -> Adapter < ' a , H > {
104- Adapter {
105- handler,
106- _phantom_data : PhantomData ,
107- }
108- }
109-
110- /// An implementation of `Handler` for a given closure return a `Future` representing the computed response
111- impl < ' a , F , R , Fut > Handler < ' a > for F
96+ /// Adapts a [`Service`] into another [`Service`].
97+ pub fn handler < ' a , R , Fut > (
98+ f : impl Fn ( Request , Context ) -> Fut ,
99+ ) -> Adapter < ' a , R , ServiceFn < impl Fn ( LambdaEvent < Request > ) -> Fut > >
112100where
113- F : Fn ( Request , Context ) -> Fut ,
114101 R : IntoResponse ,
115- Fut : Future < Output = Result < R , Error > > + ' a ,
102+ Fut : Future < Output = Result < R , Error > > ,
116103{
117- type Response = R ;
118- type Error = Error ;
119- type Fut = Fut ;
120- fn call ( & mut self , event : Request , context : Context ) -> Self :: Fut {
121- ( self ) ( event, context)
104+ Adapter {
105+ service : service_fn ( handler_wrapper ( f) ) ,
106+ _phantom_data : PhantomData ,
122107 }
123108}
124109
125110#[ doc( hidden) ]
126111pub struct TransformResponse < ' a , R , E > {
127112 request_origin : RequestOrigin ,
128- fut : Pin < Box < dyn Future < Output = Result < R , E > > + ' a > > ,
113+ fut : Pin < Box < dyn Future < Output = Result < R , E > > + Send + ' a > > ,
129114}
130115
131116impl < ' a , R , E > Future for TransformResponse < ' a , R , E >
132117where
133118 R : IntoResponse ,
134119{
135120 type Output = Result < LambdaResponse , E > ;
121+
136122 fn poll ( mut self : Pin < & mut Self > , cx : & mut TaskContext ) -> Poll < Self :: Output > {
137123 match self . fut . as_mut ( ) . poll ( cx) {
138124 Poll :: Ready ( result) => Poll :: Ready (
@@ -143,39 +129,29 @@ where
143129 }
144130}
145131
146- /// Exists only to satisfy the trait cover rule for `lambda_runtime::Handler` impl
147- ///
148- /// User code should never need to interact with this type directly. Since `Adapter` implements `Handler`
149- /// It serves as a opaque trait covering type.
150- ///
151- /// See [this article](http://smallcultfollowing.com/babysteps/blog/2015/01/14/little-orphan-impls/)
152- /// for a larger explanation of why this is necessary
153- pub struct Adapter < ' a , H : Handler < ' a > > {
154- handler : H ,
155- _phantom_data : PhantomData < & ' a H > ,
156- }
157-
158- impl < ' a , H : Handler < ' a > > Handler < ' a > for Adapter < ' a , H > {
159- type Response = H :: Response ;
160- type Error = H :: Error ;
161- type Fut = H :: Fut ;
162- fn call ( & mut self , event : Request , context : Context ) -> Self :: Fut {
163- self . handler . call ( event, context)
164- }
132+ #[ doc( hidden) ]
133+ pub struct Adapter < ' a , R , S > {
134+ service : S ,
135+ _phantom_data : PhantomData < & ' a R > ,
165136}
166137
167- impl < ' a , ' b , H : Handler < ' a > > Service < LambdaEvent < LambdaRequest < ' b > > > for Adapter < ' a , H > {
168- type Error = H :: Error ;
138+ impl < ' a , R , S > Service < LambdaEvent < LambdaRequest < ' a > > > for Adapter < ' a , R , S >
139+ where
140+ S : Service < LambdaEvent < Request > , Response = R , Error = Error > + Send ,
141+ S :: Future : Send + ' a ,
142+ R : IntoResponse ,
143+ {
169144 type Response = LambdaResponse ;
170- type Future = TransformResponse < ' a , H :: Response , H :: Error > ;
145+ type Error = Error ;
146+ type Future = TransformResponse < ' a , R , Self :: Error > ;
171147
172148 fn poll_ready ( & mut self , _cx : & mut core:: task:: Context < ' _ > ) -> core:: task:: Poll < Result < ( ) , Self :: Error > > {
173149 core:: task:: Poll :: Ready ( Ok ( ( ) ) )
174150 }
175151
176- fn call ( & mut self , req : LambdaEvent < LambdaRequest < ' _ > > ) -> Self :: Future {
152+ fn call ( & mut self , req : LambdaEvent < LambdaRequest < ' a > > ) -> Self :: Future {
177153 let request_origin = req. event . request_origin ( ) ;
178- let fut = Box :: pin ( self . handler . call ( req. event . into ( ) , req. context ) ) ;
154+ let fut = Box :: pin ( self . service . call ( LambdaEvent :: new ( req. event . into ( ) , req. context ) ) ) ;
179155 TransformResponse { request_origin, fut }
180156 }
181157}
0 commit comments