Skip to content
This repository was archived by the owner on Jun 29, 2023. It is now read-only.

Commit 4463351

Browse files
authored
Adapt lambda-http to new lambda runtime api (awslabs#217)
1 parent 8f026a0 commit 4463351

File tree

15 files changed

+1026
-559
lines changed

15 files changed

+1026
-559
lines changed

.github/workflows/build.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ jobs:
1212
- ubuntu-latest
1313
- macOS-latest
1414
rust:
15-
- 1.40.0
1615
- stable
1716
- beta
1817
- nightly

Cargo.lock

Lines changed: 253 additions & 148 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[workspace]
22
members = [
33
"lambda",
4-
"lambda-attributes"
4+
"lambda-attributes",
5+
"lambda-http"
56
]

lambda-attributes/src/lib.rs

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,20 @@ extern crate proc_macro;
22

33
use proc_macro::TokenStream;
44
use quote::quote_spanned;
5-
use syn::{spanned::Spanned, FnArg, ItemFn};
5+
use syn::{spanned::Spanned, AttributeArgs, FnArg, ItemFn, Meta, NestedMeta};
6+
7+
/// Return true if attribute macro args declares http flavor in the form `#[lambda(http)]`
8+
fn is_http(args: &AttributeArgs) -> bool {
9+
args.iter().any(|arg| match arg {
10+
NestedMeta::Meta(Meta::Path(path)) => path.is_ident("http"),
11+
_ => false,
12+
})
13+
}
614

715
#[proc_macro_attribute]
8-
pub fn lambda(_attr: TokenStream, item: TokenStream) -> TokenStream {
16+
pub fn lambda(attr: TokenStream, item: TokenStream) -> TokenStream {
917
let input = syn::parse_macro_input!(item as ItemFn);
10-
18+
let args = syn::parse_macro_input!(attr as AttributeArgs);
1119
let ret = &input.sig.output;
1220
let name = &input.sig.ident;
1321
let body = &input.block;
@@ -17,7 +25,7 @@ pub fn lambda(_attr: TokenStream, item: TokenStream) -> TokenStream {
1725

1826
if name != "main" {
1927
let tokens = quote_spanned! { name.span() =>
20-
compile_error!("only the main function can be tagged with #[lambda::main]");
28+
compile_error!("only the main function can be tagged with #[lambda]");
2129
};
2230
return TokenStream::from(tokens);
2331
}
@@ -43,16 +51,32 @@ pub fn lambda(_attr: TokenStream, item: TokenStream) -> TokenStream {
4351
let arg_name = &event.pat;
4452
let arg_type = &event.ty;
4553

46-
quote_spanned! { input.span() =>
47-
use lambda::LambdaCtx;
54+
if is_http(&args) {
55+
quote_spanned! { input.span() =>
56+
use lambda_http::lambda::LambdaCtx;
57+
58+
#(#attrs)*
59+
#asyncness fn main() {
60+
async fn actual(#arg_name: #arg_type) #ret {
61+
#body
62+
}
63+
let f = lambda_http::handler(actual);
64+
lambda_http::lambda::run(f).await.unwrap();
65+
}
66+
}
67+
} else {
68+
quote_spanned! { input.span() =>
69+
70+
use lambda::LambdaCtx;
4871

49-
#(#attrs)*
50-
#asyncness fn main() {
51-
async fn actual(#arg_name: #arg_type) #ret {
52-
#body
72+
#(#attrs)*
73+
#asyncness fn main() {
74+
async fn actual(#arg_name: #arg_type) #ret {
75+
#body
76+
}
77+
let f = lambda::handler_fn(actual);
78+
lambda::run(f).await.unwrap();
5379
}
54-
let f = lambda::handler_fn(actual);
55-
lambda::run(f).await.unwrap();
5680
}
5781
}
5882
}

lambda-http/Cargo.toml

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
[package]
22
name = "lambda_http"
3-
version = "0.1.1"
3+
version = "0.2.0-beta.1"
44
authors = ["Doug Tangren"]
55
edition = "2018"
6-
description = "Rust API Gateway proxy event interfaces for AWS Lambda"
6+
description = "Application Load Balancer and API Gateway event types for AWS Lambda"
77
keywords = ["AWS", "Lambda", "APIGateway", "ALB", "API"]
88
license = "Apache-2.0"
99
homepage = "https://github.com/awslabs/aws-lambda-rust-runtime"
@@ -16,18 +16,16 @@ travis-ci = { repository = "awslabs/aws-lambda-rust-runtime" }
1616
maintenance = { status = "actively-developed" }
1717

1818
[dependencies]
19-
http = "0.1"
19+
base64 = "0.12"
20+
http = "0.2"
21+
lambda = { path = "../lambda", version = "0.1" }
22+
lambda-attributes = { path = "../lambda-attributes", version = "0.1" }
2023
serde = "^1"
21-
serde_json = "^1"
2224
serde_derive = "^1"
23-
lambda = { path = "../lambda" }
24-
tokio = "^0.1"
25-
base64 = "0.10"
26-
failure = "0.1"
27-
failure_derive = "0.1"
28-
serde_urlencoded = "0.5"
25+
serde_json = "^1"
26+
serde_urlencoded = "0.6"
2927

3028
[dev-dependencies]
3129
log = "^0.4"
3230
maplit = "1.0"
33-
simple_logger = "^1"
31+
tokio = { version = "0.2", features = ["macros"] }

lambda-http/examples/basic.rs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,19 @@
1-
use std::error::Error;
1+
use lambda_http::{handler, lambda, IntoResponse, Request, RequestExt, Response};
22

3-
use lambda_http::{lambda, IntoResponse, Request, RequestExt, Response};
4-
use lambda_runtime::{error::HandlerError, Context};
5-
use log::{self, error};
6-
use simple_logger;
7-
8-
fn main() -> Result<(), Box<dyn Error>> {
9-
simple_logger::init_with_level(log::Level::Debug)?;
10-
lambda!(my_handler);
3+
type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
114

5+
#[tokio::main]
6+
async fn main() -> Result<(), Error> {
7+
lambda::run(handler(func)).await?;
128
Ok(())
139
}
1410

15-
fn my_handler(e: Request, c: Context) -> Result<impl IntoResponse, HandlerError> {
16-
Ok(match e.query_string_parameters().get("first_name") {
11+
async fn func(event: Request) -> Result<impl IntoResponse, Error> {
12+
Ok(match event.query_string_parameters().get("first_name") {
1713
Some(first_name) => format!("Hello, {}!", first_name).into_response(),
18-
_ => {
19-
error!("Empty first name in request {}", c.aws_request_id);
20-
Response::builder()
21-
.status(400)
22-
.body("Empty first name".into())
23-
.expect("failed to render response")
24-
}
14+
_ => Response::builder()
15+
.status(400)
16+
.body("Empty first name".into())
17+
.expect("failed to render response"),
2518
})
2619
}

lambda-http/examples/hello.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use lambda_http::{lambda, IntoResponse, Request};
2+
3+
type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
4+
5+
#[lambda(http)]
6+
#[tokio::main]
7+
async fn main(_: Request) -> Result<impl IntoResponse, Error> {
8+
Ok("👋 world")
9+
}

lambda-http/src/body.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,22 @@ pub enum Body {
6868
Binary(Vec<u8>),
6969
}
7070

71+
impl Body {
72+
/// Decodes body, if needed.
73+
///
74+
/// # Panics
75+
///
76+
/// Panics when aws communicates to handler that request is base64 encoded but
77+
/// it can not be base64 decoded
78+
pub(crate) fn from_maybe_encoded(is_base64_encoded: bool, body: Cow<'_, str>) -> Body {
79+
if is_base64_encoded {
80+
Body::from(::base64::decode(body.as_ref()).expect("failed to decode aws base64 encoded body"))
81+
} else {
82+
Body::from(body.as_ref())
83+
}
84+
}
85+
}
86+
7187
impl Default for Body {
7288
fn default() -> Self {
7389
Body::Empty

0 commit comments

Comments
 (0)