1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
pub mod body;
pub mod error;
pub mod request;
pub mod response;
use body::Body;
use error::VercelError;
pub use lambda_http;
use lambda_http::{service_fn, tower::ServiceBuilder};
pub use lambda_runtime;
use lambda_runtime::LambdaEvent;
use request::{VercelEvent, VercelRequest};
pub use response::IntoResponse;
use response::VercelResponse;
use std::future::Future;
use tracing::{debug, error};

pub type ProxyRequest = lambda_http::http::Request<Body>;
pub type ProxyError = lambda_http::http::Error;

pub async fn run<
    T: FnMut(ProxyRequest) -> F,
    F: Future<Output = Result<impl IntoResponse, ProxyError>>,
>(
    f: T,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let handler = ServiceBuilder::new()
        .map_request(process_request)
        .map_response(process_response)
        .map_err(process_error)
        .service(service_fn(f));

    lambda_runtime::run(handler).await
}

pub fn process_request(lambda_event: LambdaEvent<VercelEvent>) -> lambda_http::http::Request<Body> {
    dbg!(&lambda_event);
    let (event, _context) = lambda_event.into_parts();
    let parse_result = serde_json::from_str::<VercelRequest>(&event.body);

    match parse_result {
        Ok(request) => {
            debug!("Deserialized Vercel proxy request successfully");
            debug!("Request: {:?}", request);
            let http_req: lambda_http::http::Request<Body> = request.into();
            http_req.map(|b| b)
        }
        Err(e) => {
            error!("Could not deserialize event body to VercelRequest {:?}", e);
            panic!("Could not deserialize event body to VercelRequest {}", e);
        }
    }
}

pub fn process_response(response: impl IntoResponse) -> VercelResponse {
    VercelResponse::from(response.into_response())
}

pub fn process_error(error: lambda_http::http::Error) -> VercelError {
    error.into()
}