pub use http::{self, Response};
use lambda_runtime::{self as lambda, Context};
use log::{self, debug, error};
use serde_json::Error;
use tokio::runtime::Runtime as TokioRuntime;
mod body;
pub mod error;
pub mod request;
mod response;
mod strmap;
pub use crate::{body::Body, response::IntoResponse, strmap::StrMap};
use crate::{
error::VercelError,
request::{VercelEvent, VercelRequest},
response::VercelResponse,
};
pub type Request = http::Request<Body>;
pub trait Handler<R, B, E> {
fn run(&mut self, event: http::Request<B>) -> Result<R, E>;
}
impl<Function, R, B, E> Handler<R, B, E> for Function
where
Function: FnMut(http::Request<B>) -> Result<R, E>,
{
fn run(&mut self, event: http::Request<B>) -> Result<R, E> {
(*self)(event)
}
}
pub fn start<R, B, E>(f: impl Handler<R, B, E>, runtime: Option<TokioRuntime>)
where
B: From<Body>,
E: Into<VercelError>,
R: IntoResponse,
{
let mut func = f;
lambda::start(
|e: VercelEvent, _ctx: Context| {
let req_str = e.body;
let parse_result: Result<VercelRequest, Error> = serde_json::from_str(&req_str);
match parse_result {
Ok(req) => {
debug!("Deserialized Vercel proxy request successfully");
let request: http::Request<Body> = req.into();
func.run(request.map(|b| b.into()))
.map(|resp| VercelResponse::from(resp.into_response()))
.map_err(|e| e.into())
}
Err(e) => {
error!("Could not deserialize event body to VercelRequest {}", e);
panic!("Could not deserialize event body to VercelRequest {}", e);
}
}
},
runtime,
)
}
#[macro_export]
macro_rules! lambda {
($handler:expr) => {
$crate::start($handler, None)
};
($handler:expr, $runtime:expr) => {
$crate::start($handler, Some($runtime))
};
($handler:ident) => {
$crate::start($handler, None)
};
($handler:ident, $runtime:expr) => {
$crate::start($handler, Some($runtime))
};
}