From a65c1e8c6b5a8faba47233ed0115d864c6c749de Mon Sep 17 00:00:00 2001 From: softprops Date: Fri, 26 Jun 2020 23:18:53 -0400 Subject: [PATCH 1/3] make LambdaCtx a first class part of the handler api --- lambda-attributes/src/lib.rs | 36 +++++++++++-------- .../examples/hello-http-without-macros.rs | 8 +++-- lambda-http/examples/hello-http.rs | 7 ++-- lambda-http/src/ext.rs | 5 +-- lambda-http/src/lib.rs | 27 +++++++------- lambda/examples/hello-with-ctx.rs | 4 +-- lambda/examples/hello-without-macro.rs | 4 +-- lambda/examples/hello.rs | 4 +-- lambda/src/lib.rs | 26 ++++++-------- 9 files changed, 66 insertions(+), 55 deletions(-) diff --git a/lambda-attributes/src/lib.rs b/lambda-attributes/src/lib.rs index 6f477495..a17fdfad 100644 --- a/lambda-attributes/src/lib.rs +++ b/lambda-attributes/src/lib.rs @@ -38,28 +38,37 @@ pub fn lambda(attr: TokenStream, item: TokenStream) -> TokenStream { } let result = match inputs.len() { - 1 => { - let event = match inputs.first().unwrap() { + 2 => { + let event = match inputs.first().expect("expected event argument") { FnArg::Typed(arg) => arg, _ => { let tokens = quote_spanned! { inputs.span() => - compile_error!("fn main must take a fully formed argument"); + compile_error!("fn main's first argument must be fully formed"); }; return TokenStream::from(tokens); } }; - let arg_name = &event.pat; - let arg_type = &event.ty; + let event_name = &event.pat; + let event_type = &event.ty; + let context = match inputs.iter().nth(1).expect("expected context argument") { + FnArg::Typed(arg) => arg, + _ => { + let tokens = quote_spanned! { inputs.span() => + compile_error!("fn main's second argument must be fully formed"); + }; + return TokenStream::from(tokens); + } + }; + let context_name = &context.pat; + let context_type = &context.ty; if is_http(&args) { quote_spanned! { input.span() => - use lambda_http::lambda::LambdaCtx; #(#attrs)* #asyncness fn main() { - async fn actual(#arg_name: #arg_type) #ret { - #body - } + async fn actual(#event_name: #event_type, #context_name: #context_type) #ret #body + let f = lambda_http::handler(actual); lambda_http::lambda::run(f).await.unwrap(); } @@ -67,13 +76,10 @@ pub fn lambda(attr: TokenStream, item: TokenStream) -> TokenStream { } else { quote_spanned! { input.span() => - use lambda::LambdaCtx; - #(#attrs)* #asyncness fn main() { - async fn actual(#arg_name: #arg_type) #ret { - #body - } + async fn actual(#event_name: #event_type, #context_name: #context_type) #ret #body + let f = lambda::handler_fn(actual); lambda::run(f).await.unwrap(); } @@ -82,7 +88,7 @@ pub fn lambda(attr: TokenStream, item: TokenStream) -> TokenStream { } _ => { let tokens = quote_spanned! { inputs.span() => - compile_error!("The #[lambda] macro can accept only a single argument."); + compile_error!("The #[lambda] macro can expects two arguments: a triggered event and lambda context."); }; return TokenStream::from(tokens); } diff --git a/lambda-http/examples/hello-http-without-macros.rs b/lambda-http/examples/hello-http-without-macros.rs index db740c8e..289ade6d 100644 --- a/lambda-http/examples/hello-http-without-macros.rs +++ b/lambda-http/examples/hello-http-without-macros.rs @@ -1,4 +1,8 @@ -use lambda_http::{handler, lambda, IntoResponse, Request, RequestExt, Response}; +use lambda_http::{ + handler, + lambda::{self, LambdaCtx}, + IntoResponse, Request, RequestExt, Response, +}; type Error = Box; @@ -8,7 +12,7 @@ async fn main() -> Result<(), Error> { Ok(()) } -async fn func(event: Request) -> Result { +async fn func(event: Request, _: LambdaCtx) -> Result { Ok(match event.query_string_parameters().get("first_name") { Some(first_name) => format!("Hello, {}!", first_name).into_response(), _ => Response::builder() diff --git a/lambda-http/examples/hello-http.rs b/lambda-http/examples/hello-http.rs index 978a50e3..f303e9d7 100644 --- a/lambda-http/examples/hello-http.rs +++ b/lambda-http/examples/hello-http.rs @@ -1,9 +1,12 @@ -use lambda_http::{lambda, IntoResponse, Request}; +use lambda_http::{ + lambda::{lambda, LambdaCtx}, + IntoResponse, Request, +}; type Error = Box; #[lambda(http)] #[tokio::main] -async fn main(_: Request) -> Result { +async fn main(_: Request, _: LambdaCtx) -> Result { Ok("👋 world") } diff --git a/lambda-http/src/ext.rs b/lambda-http/src/ext.rs index 761a6417..28fc0b34 100644 --- a/lambda-http/src/ext.rs +++ b/lambda-http/src/ext.rs @@ -67,7 +67,7 @@ impl Error for PayloadError { /// as well as `{"x":1, "y":2}` respectively. /// /// ```rust,no_run -/// use lambda_http::{handler, lambda, Body, IntoResponse, Request, Response, RequestExt}; +/// use lambda_http::{handler, lambda::{self, LambdaCtx}, Body, IntoResponse, Request, Response, RequestExt}; /// use serde_derive::Deserialize; /// /// type Error = Box; @@ -87,7 +87,8 @@ impl Error for PayloadError { /// } /// /// async fn add( -/// request: Request +/// request: Request, +/// _: LambdaCtx /// ) -> Result, Error> { /// let args: Args = request.payload() /// .unwrap_or_else(|_parse_err| None) diff --git a/lambda-http/src/lib.rs b/lambda-http/src/lib.rs index 077356bf..dffb2316 100644 --- a/lambda-http/src/lib.rs +++ b/lambda-http/src/lib.rs @@ -22,13 +22,13 @@ //! The full body of your `main` function will be executed on **every** invocation of your lambda task. //! //! ```rust,no_run -//! use lambda_http::{lambda, Request, IntoResponse}; +//! use lambda_http::{lambda::{lambda, LambdaCtx}, Request, IntoResponse}; //! //! type Error = Box; //! //! #[lambda(http)] //! #[tokio::main] -//! async fn main(_: Request) -> Result { +//! async fn main(_: Request, _: LambdaCtx) -> Result { //! Ok("👋 world!") //! } //! ``` @@ -48,7 +48,7 @@ //! async fn main() -> Result<(), Error> { //! // initialize dependencies once here for the lifetime of your //! // lambda task -//! lambda::run(handler(|request| async { Ok("👋 world!") })).await?; +//! lambda::run(handler(|request, context| async { Ok("👋 world!") })).await?; //! Ok(()) //! } //! @@ -60,7 +60,7 @@ //! with the [`RequestExt`](trait.RequestExt.html) trait. //! //! ```rust,no_run -//! use lambda_http::{handler, lambda, IntoResponse, Request, RequestExt}; +//! use lambda_http::{handler, lambda::{self, LambdaCtx}, IntoResponse, Request, RequestExt}; //! //! type Error = Box; //! @@ -72,6 +72,7 @@ //! //! async fn hello( //! request: Request, +//! _: LambdaCtx //! ) -> Result { //! Ok(format!( //! "hello {}", @@ -90,7 +91,7 @@ extern crate maplit; pub use http::{self, Response}; use lambda::Handler as LambdaHandler; -pub use lambda::{self}; +pub use lambda::{self, LambdaCtx}; pub use lambda_attributes::lambda; mod body; @@ -123,7 +124,7 @@ pub trait Handler: Sized { /// The type of Future this Handler will return type Fut: Future> + 'static; /// Function used to execute handler behavior - fn call(&mut self, event: Request) -> Self::Fut; + fn call(&mut self, event: Request, context: LambdaCtx) -> Self::Fut; } /// Adapts a [`Handler`](trait.Handler.html) to the `lambda::run` interface @@ -134,15 +135,15 @@ pub fn handler(handler: H) -> Adapter { /// An implementation of `Handler` for a given closure return a `Future` representing the computed response impl Handler for F where - F: FnMut(Request) -> Fut, + F: FnMut(Request, LambdaCtx) -> Fut, R: IntoResponse, Fut: Future> + Send + 'static, { type Response = R; type Error = Error; type Fut = Fut; - fn call(&mut self, event: Request) -> Self::Fut { - (*self)(event) + fn call(&mut self, event: Request, context: LambdaCtx) -> Self::Fut { + (*self)(event, context) } } @@ -182,17 +183,17 @@ impl Handler for Adapter { type Response = H::Response; type Error = H::Error; type Fut = H::Fut; - fn call(&mut self, event: Request) -> Self::Fut { - self.handler.call(event) + fn call(&mut self, event: Request, context: LambdaCtx) -> Self::Fut { + self.handler.call(event, context) } } impl LambdaHandler, LambdaResponse> for Adapter { type Error = H::Error; type Fut = TransformResponse; - fn call(&mut self, event: LambdaRequest<'_>) -> Self::Fut { + fn call(&mut self, event: LambdaRequest<'_>, context: LambdaCtx) -> Self::Fut { let is_alb = event.is_alb(); - let fut = Box::pin(self.handler.call(event.into())); + let fut = Box::pin(self.handler.call(event.into(), context)); TransformResponse { is_alb, fut } } } diff --git a/lambda/examples/hello-with-ctx.rs b/lambda/examples/hello-with-ctx.rs index 957c2a58..6deada5e 100644 --- a/lambda/examples/hello-with-ctx.rs +++ b/lambda/examples/hello-with-ctx.rs @@ -1,10 +1,10 @@ -use lambda::lambda; +use lambda::{lambda, LambdaCtx}; use serde_json::Value; type Error = Box; #[lambda] #[tokio::main] -async fn main(event: Value) -> Result { +async fn main(event: Value, _: LambdaCtx) -> Result { Ok(event) } diff --git a/lambda/examples/hello-without-macro.rs b/lambda/examples/hello-without-macro.rs index dd20bd10..eb5952e5 100644 --- a/lambda/examples/hello-without-macro.rs +++ b/lambda/examples/hello-without-macro.rs @@ -1,4 +1,4 @@ -use lambda::handler_fn; +use lambda::{handler_fn, LambdaCtx}; use serde_json::Value; type Error = Box; @@ -10,6 +10,6 @@ async fn main() -> Result<(), Error> { Ok(()) } -async fn func(event: Value) -> Result { +async fn func(event: Value, _: LambdaCtx) -> Result { Ok(event) } diff --git a/lambda/examples/hello.rs b/lambda/examples/hello.rs index 957c2a58..6deada5e 100644 --- a/lambda/examples/hello.rs +++ b/lambda/examples/hello.rs @@ -1,10 +1,10 @@ -use lambda::lambda; +use lambda::{lambda, LambdaCtx}; use serde_json::Value; type Error = Box; #[lambda] #[tokio::main] -async fn main(event: Value) -> Result { +async fn main(event: Value, _: LambdaCtx) -> Result { Ok(event) } diff --git a/lambda/src/lib.rs b/lambda/src/lib.rs index 17067d83..c5bf09bb 100644 --- a/lambda/src/lib.rs +++ b/lambda/src/lib.rs @@ -17,22 +17,19 @@ //! to the the `lambda::run` function, which launches and runs the Lambda runtime. //! //! An asynchronous function annotated with the `#[lambda]` attribute must -//! accept an argument of type `A` which implements [`serde::Deserialize`] and +//! accept an argument of type `A` which implements [`serde::Deserialize`], a [`lambda:L:LambdaCtx`] and //! return a `Result`, where `B` implements [`serde::Serializable`]. `E` is //! any type that implements `Into>`. //! -//! Optionally, the `#[lambda]` annotated function can accept an argument -//! of [`lambda::LambdaCtx`]. -//! //! ```no_run -//! use lambda::{lambda}; +//! use lambda::{lambda, LambdaCtx}; //! use serde_json::Value; //! //! type Error = Box; //! //! #[lambda] //! #[tokio::main] -//! async fn main(event: Value) -> Result { +//! async fn main(event: Value, _: LambdaCtx) -> Result { //! Ok(event) //! } //! ``` @@ -102,8 +99,8 @@ pub trait Handler { type Error; /// The future response value of this handler. type Fut: Future>; - /// Process the incoming event and return the response asynchronously. - fn call(&mut self, event: A) -> Self::Fut; + /// Process the incoming event and `LambdaCtx` then return the response asynchronously. + fn call(&mut self, event: A, context: LambdaCtx) -> Self::Fut; } /// Returns a new `HandlerFn` with the given closure. @@ -119,15 +116,14 @@ pub struct HandlerFn { impl Handler for HandlerFn where - F: Fn(A) -> Fut, + F: Fn(A, LambdaCtx) -> Fut, Fut: Future> + Send, Error: Into + fmt::Debug, { type Error = Error; type Fut = Fut; - fn call(&mut self, req: A) -> Self::Fut { - // we pass along the context here - (self.f)(req) + fn call(&mut self, req: A, ctx: LambdaCtx) -> Self::Fut { + (self.f)(req, ctx) } } @@ -136,7 +132,7 @@ where /// /// # Example /// ```no_run -/// use lambda::{handler_fn}; +/// use lambda::{handler_fn, LambdaCtx}; /// use serde_json::Value; /// /// type Error = Box; @@ -148,7 +144,7 @@ where /// Ok(()) /// } /// -/// async fn func(event: Value) -> Result { +/// async fn func(event: Value, _: LambdaCtx) -> Result { /// Ok(event) /// } /// ``` @@ -216,7 +212,7 @@ where let body = serde_json::from_slice(&body)?; let request_id = &ctx.request_id.clone(); - let f = INVOCATION_CTX.scope(ctx, { handler.call(body) }); + let f = INVOCATION_CTX.scope(ctx.clone(), { handler.call(body, ctx) }); let req = match f.await { Ok(res) => EventCompletionRequest { request_id, body: res }.into_req()?, From e2b4de0e1a369fa7f1bf67dadb98ca2e39434897 Mon Sep 17 00:00:00 2001 From: softprops Date: Sat, 27 Jun 2020 22:54:33 -0400 Subject: [PATCH 2/3] rename lambda::LambdaCtx to lambda::Context --- .../examples/hello-http-without-macros.rs | 4 +-- lambda-http/examples/hello-http.rs | 4 +-- lambda-http/src/ext.rs | 4 +-- lambda-http/src/lib.rs | 24 ++++++++--------- lambda/examples/hello-with-ctx.rs | 4 +-- lambda/examples/hello-without-macro.rs | 4 +-- lambda/examples/hello.rs | 4 +-- lambda/src/lib.rs | 26 +++++++++---------- lambda/src/types.rs | 6 ++--- 9 files changed, 40 insertions(+), 40 deletions(-) diff --git a/lambda-http/examples/hello-http-without-macros.rs b/lambda-http/examples/hello-http-without-macros.rs index 289ade6d..0a609651 100644 --- a/lambda-http/examples/hello-http-without-macros.rs +++ b/lambda-http/examples/hello-http-without-macros.rs @@ -1,6 +1,6 @@ use lambda_http::{ handler, - lambda::{self, LambdaCtx}, + lambda::{self, Context}, IntoResponse, Request, RequestExt, Response, }; @@ -12,7 +12,7 @@ async fn main() -> Result<(), Error> { Ok(()) } -async fn func(event: Request, _: LambdaCtx) -> Result { +async fn func(event: Request, _: Context) -> Result { Ok(match event.query_string_parameters().get("first_name") { Some(first_name) => format!("Hello, {}!", first_name).into_response(), _ => Response::builder() diff --git a/lambda-http/examples/hello-http.rs b/lambda-http/examples/hello-http.rs index f303e9d7..f8fa1f16 100644 --- a/lambda-http/examples/hello-http.rs +++ b/lambda-http/examples/hello-http.rs @@ -1,5 +1,5 @@ use lambda_http::{ - lambda::{lambda, LambdaCtx}, + lambda::{lambda, Context}, IntoResponse, Request, }; @@ -7,6 +7,6 @@ type Error = Box; #[lambda(http)] #[tokio::main] -async fn main(_: Request, _: LambdaCtx) -> Result { +async fn main(_: Request, _: Context) -> Result { Ok("👋 world") } diff --git a/lambda-http/src/ext.rs b/lambda-http/src/ext.rs index 28fc0b34..dd08ae73 100644 --- a/lambda-http/src/ext.rs +++ b/lambda-http/src/ext.rs @@ -67,7 +67,7 @@ impl Error for PayloadError { /// as well as `{"x":1, "y":2}` respectively. /// /// ```rust,no_run -/// use lambda_http::{handler, lambda::{self, LambdaCtx}, Body, IntoResponse, Request, Response, RequestExt}; +/// use lambda_http::{handler, lambda::{self, Context}, Body, IntoResponse, Request, Response, RequestExt}; /// use serde_derive::Deserialize; /// /// type Error = Box; @@ -88,7 +88,7 @@ impl Error for PayloadError { /// /// async fn add( /// request: Request, -/// _: LambdaCtx +/// _: Context /// ) -> Result, Error> { /// let args: Args = request.payload() /// .unwrap_or_else(|_parse_err| None) diff --git a/lambda-http/src/lib.rs b/lambda-http/src/lib.rs index dffb2316..f26fa351 100644 --- a/lambda-http/src/lib.rs +++ b/lambda-http/src/lib.rs @@ -22,13 +22,13 @@ //! The full body of your `main` function will be executed on **every** invocation of your lambda task. //! //! ```rust,no_run -//! use lambda_http::{lambda::{lambda, LambdaCtx}, Request, IntoResponse}; +//! use lambda_http::{lambda::{lambda, Context}, Request, IntoResponse}; //! //! type Error = Box; //! //! #[lambda(http)] //! #[tokio::main] -//! async fn main(_: Request, _: LambdaCtx) -> Result { +//! async fn main(_: Request, _: Context) -> Result { //! Ok("👋 world!") //! } //! ``` @@ -60,7 +60,7 @@ //! with the [`RequestExt`](trait.RequestExt.html) trait. //! //! ```rust,no_run -//! use lambda_http::{handler, lambda::{self, LambdaCtx}, IntoResponse, Request, RequestExt}; +//! use lambda_http::{handler, lambda::{self, Context}, IntoResponse, Request, RequestExt}; //! //! type Error = Box; //! @@ -72,7 +72,7 @@ //! //! async fn hello( //! request: Request, -//! _: LambdaCtx +//! _: Context //! ) -> Result { //! Ok(format!( //! "hello {}", @@ -91,7 +91,7 @@ extern crate maplit; pub use http::{self, Response}; use lambda::Handler as LambdaHandler; -pub use lambda::{self, LambdaCtx}; +pub use lambda::{self, Context}; pub use lambda_attributes::lambda; mod body; @@ -104,7 +104,7 @@ use crate::{request::LambdaRequest, response::LambdaResponse}; use std::{ future::Future, pin::Pin, - task::{Context, Poll}, + task::{Context as TaskContext, Poll}, }; /// Error type that lambdas may result in @@ -124,7 +124,7 @@ pub trait Handler: Sized { /// The type of Future this Handler will return type Fut: Future> + 'static; /// Function used to execute handler behavior - fn call(&mut self, event: Request, context: LambdaCtx) -> Self::Fut; + fn call(&mut self, event: Request, context: Context) -> Self::Fut; } /// Adapts a [`Handler`](trait.Handler.html) to the `lambda::run` interface @@ -135,14 +135,14 @@ pub fn handler(handler: H) -> Adapter { /// An implementation of `Handler` for a given closure return a `Future` representing the computed response impl Handler for F where - F: FnMut(Request, LambdaCtx) -> Fut, + F: FnMut(Request, Context) -> Fut, R: IntoResponse, Fut: Future> + Send + 'static, { type Response = R; type Error = Error; type Fut = Fut; - fn call(&mut self, event: Request, context: LambdaCtx) -> Self::Fut { + fn call(&mut self, event: Request, context: Context) -> Self::Fut { (*self)(event, context) } } @@ -158,7 +158,7 @@ where R: IntoResponse, { type Output = Result; - fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + fn poll(mut self: Pin<&mut Self>, cx: &mut TaskContext) -> Poll { match self.fut.as_mut().poll(cx) { Poll::Ready(result) => { Poll::Ready(result.map(|resp| LambdaResponse::from_response(self.is_alb, resp.into_response()))) @@ -183,7 +183,7 @@ impl Handler for Adapter { type Response = H::Response; type Error = H::Error; type Fut = H::Fut; - fn call(&mut self, event: Request, context: LambdaCtx) -> Self::Fut { + fn call(&mut self, event: Request, context: Context) -> Self::Fut { self.handler.call(event, context) } } @@ -191,7 +191,7 @@ impl Handler for Adapter { impl LambdaHandler, LambdaResponse> for Adapter { type Error = H::Error; type Fut = TransformResponse; - fn call(&mut self, event: LambdaRequest<'_>, context: LambdaCtx) -> Self::Fut { + fn call(&mut self, event: LambdaRequest<'_>, context: Context) -> Self::Fut { let is_alb = event.is_alb(); let fut = Box::pin(self.handler.call(event.into(), context)); TransformResponse { is_alb, fut } diff --git a/lambda/examples/hello-with-ctx.rs b/lambda/examples/hello-with-ctx.rs index 6deada5e..99472874 100644 --- a/lambda/examples/hello-with-ctx.rs +++ b/lambda/examples/hello-with-ctx.rs @@ -1,10 +1,10 @@ -use lambda::{lambda, LambdaCtx}; +use lambda::{lambda, Context}; use serde_json::Value; type Error = Box; #[lambda] #[tokio::main] -async fn main(event: Value, _: LambdaCtx) -> Result { +async fn main(event: Value, _: Context) -> Result { Ok(event) } diff --git a/lambda/examples/hello-without-macro.rs b/lambda/examples/hello-without-macro.rs index eb5952e5..2aec334f 100644 --- a/lambda/examples/hello-without-macro.rs +++ b/lambda/examples/hello-without-macro.rs @@ -1,4 +1,4 @@ -use lambda::{handler_fn, LambdaCtx}; +use lambda::{handler_fn, Context}; use serde_json::Value; type Error = Box; @@ -10,6 +10,6 @@ async fn main() -> Result<(), Error> { Ok(()) } -async fn func(event: Value, _: LambdaCtx) -> Result { +async fn func(event: Value, _: Context) -> Result { Ok(event) } diff --git a/lambda/examples/hello.rs b/lambda/examples/hello.rs index 6deada5e..99472874 100644 --- a/lambda/examples/hello.rs +++ b/lambda/examples/hello.rs @@ -1,10 +1,10 @@ -use lambda::{lambda, LambdaCtx}; +use lambda::{lambda, Context}; use serde_json::Value; type Error = Box; #[lambda] #[tokio::main] -async fn main(event: Value, _: LambdaCtx) -> Result { +async fn main(event: Value, _: Context) -> Result { Ok(event) } diff --git a/lambda/src/lib.rs b/lambda/src/lib.rs index c5bf09bb..adf50f83 100644 --- a/lambda/src/lib.rs +++ b/lambda/src/lib.rs @@ -17,23 +17,23 @@ //! to the the `lambda::run` function, which launches and runs the Lambda runtime. //! //! An asynchronous function annotated with the `#[lambda]` attribute must -//! accept an argument of type `A` which implements [`serde::Deserialize`], a [`lambda:L:LambdaCtx`] and +//! accept an argument of type `A` which implements [`serde::Deserialize`], a [`lambda::Context`] and //! return a `Result`, where `B` implements [`serde::Serializable`]. `E` is //! any type that implements `Into>`. //! //! ```no_run -//! use lambda::{lambda, LambdaCtx}; +//! use lambda::{lambda, Context}; //! use serde_json::Value; //! //! type Error = Box; //! //! #[lambda] //! #[tokio::main] -//! async fn main(event: Value, _: LambdaCtx) -> Result { +//! async fn main(event: Value, _: Context) -> Result { //! Ok(event) //! } //! ``` -pub use crate::types::LambdaCtx; +pub use crate::types::Context; use client::Client; use futures::stream::{Stream, StreamExt}; use genawaiter::{sync::gen, yield_}; @@ -90,7 +90,7 @@ impl Config { } tokio::task_local! { - pub static INVOCATION_CTX: types::LambdaCtx; + pub static INVOCATION_CTX: types::Context; } /// A trait describing an asynchronous function `A` to `B. @@ -99,8 +99,8 @@ pub trait Handler { type Error; /// The future response value of this handler. type Fut: Future>; - /// Process the incoming event and `LambdaCtx` then return the response asynchronously. - fn call(&mut self, event: A, context: LambdaCtx) -> Self::Fut; + /// Process the incoming event and `Context` then return the response asynchronously. + fn call(&mut self, event: A, context: Context) -> Self::Fut; } /// Returns a new `HandlerFn` with the given closure. @@ -116,13 +116,13 @@ pub struct HandlerFn { impl Handler for HandlerFn where - F: Fn(A, LambdaCtx) -> Fut, + F: Fn(A, Context) -> Fut, Fut: Future> + Send, Error: Into + fmt::Debug, { type Error = Error; type Fut = Fut; - fn call(&mut self, req: A, ctx: LambdaCtx) -> Self::Fut { + fn call(&mut self, req: A, ctx: Context) -> Self::Fut { (self.f)(req, ctx) } } @@ -132,7 +132,7 @@ where /// /// # Example /// ```no_run -/// use lambda::{handler_fn, LambdaCtx}; +/// use lambda::{handler_fn, Context}; /// use serde_json::Value; /// /// type Error = Box; @@ -144,7 +144,7 @@ where /// Ok(()) /// } /// -/// async fn func(event: Value, _: LambdaCtx) -> Result { +/// async fn func(event: Value, _: Context) -> Result { /// Ok(event) /// } /// ``` @@ -207,12 +207,12 @@ where let event = event?; let (parts, body) = event.into_parts(); - let ctx: LambdaCtx = LambdaCtx::try_from(parts.headers)?; + let ctx: Context = Context::try_from(parts.headers)?; let body = hyper::body::to_bytes(body).await?; let body = serde_json::from_slice(&body)?; let request_id = &ctx.request_id.clone(); - let f = INVOCATION_CTX.scope(ctx.clone(), { handler.call(body, ctx) }); + let f = INVOCATION_CTX.scope(ctx.clone(), handler.call(body, ctx)); let req = match f.await { Ok(res) => EventCompletionRequest { request_id, body: res }.into_req()?, diff --git a/lambda/src/types.rs b/lambda/src/types.rs index 2efcb3d1..c3e11498 100644 --- a/lambda/src/types.rs +++ b/lambda/src/types.rs @@ -94,7 +94,7 @@ pub struct CognitoIdentity { /// and the headers returned by the poll request to the Runtime APIs. #[non_exhaustive] #[derive(Clone, Debug, PartialEq, Default)] -pub struct LambdaCtx { +pub struct Context { /// The AWS request ID generated by the Lambda service. pub request_id: String, /// The execution deadline for the current invocation in milliseconds. @@ -116,10 +116,10 @@ pub struct LambdaCtx { pub env_config: Config, } -impl TryFrom for LambdaCtx { +impl TryFrom for Context { type Error = Error; fn try_from(headers: HeaderMap) -> Result { - let ctx = LambdaCtx { + let ctx = Context { request_id: headers["lambda-runtime-aws-request-id"] .to_str() .expect("Missing Request ID") From 9dc10cc9ac848f6020efe312f5c1d5f9a5c64b1f Mon Sep 17 00:00:00 2001 From: softprops Date: Sat, 27 Jun 2020 22:56:48 -0400 Subject: [PATCH 3/3] remove a non helpful example. all handlers have a ctx now --- lambda/examples/hello-with-ctx.rs | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 lambda/examples/hello-with-ctx.rs diff --git a/lambda/examples/hello-with-ctx.rs b/lambda/examples/hello-with-ctx.rs deleted file mode 100644 index 99472874..00000000 --- a/lambda/examples/hello-with-ctx.rs +++ /dev/null @@ -1,10 +0,0 @@ -use lambda::{lambda, Context}; -use serde_json::Value; - -type Error = Box; - -#[lambda] -#[tokio::main] -async fn main(event: Value, _: Context) -> Result { - Ok(event) -}