1pub use http::{self, Response};
2use lambda_runtime::{self as lambda, Context};
3use log::{self, debug, error};
4use serde_json::Error;
5use tokio::runtime::Runtime as TokioRuntime;
6
7mod body;
8pub mod error;
9pub mod request;
10mod response;
11mod strmap;
12
13pub use crate::{body::Body, response::IntoResponse, strmap::StrMap};
14use crate::{
15 error::NowError,
16 request::{NowEvent, NowRequest},
17 response::NowResponse,
18};
19
20pub type Request = http::Request<Body>;
22
23pub trait Handler<R, B, E> {
25 fn run(&mut self, event: http::Request<B>) -> Result<R, E>;
27}
28
29impl<Function, R, B, E> Handler<R, B, E> for Function
30where
31 Function: FnMut(http::Request<B>) -> Result<R, E>,
32{
33 fn run(&mut self, event: http::Request<B>) -> Result<R, E> {
34 (*self)(event)
35 }
36}
37
38pub fn start<R, B, E>(f: impl Handler<R, B, E>, runtime: Option<TokioRuntime>)
47where
48 B: From<Body>,
49 E: Into<NowError>,
50 R: IntoResponse,
51{
52 let mut func = f;
54 lambda::start(
55 |e: NowEvent, _ctx: Context| {
56 let req_str = e.body;
57 let parse_result: Result<NowRequest, Error> = serde_json::from_str(&req_str);
58 match parse_result {
59 Ok(req) => {
60 debug!("Deserialized Now proxy request successfully");
61 let request: http::Request<Body> = req.into();
62 func.run(request.map(|b| b.into()))
63 .map(|resp| NowResponse::from(resp.into_response()))
64 .map_err(|e| e.into())
65 }
66 Err(e) => {
67 error!("Could not deserialize event body to NowRequest {}", e);
68 panic!("Could not deserialize event body to NowRequest {}", e);
69 }
70 }
71 },
72 runtime,
73 )
74}
75
76#[macro_export]
78macro_rules! lambda {
79 ($handler:expr) => {
80 $crate::start($handler, None)
81 };
82 ($handler:expr, $runtime:expr) => {
83 $crate::start($handler, Some($runtime))
84 };
85 ($handler:ident) => {
86 $crate::start($handler, None)
87 };
88 ($handler:ident, $runtime:expr) => {
89 $crate::start($handler, Some($runtime))
90 };
91}