use std::ops::Deref;
use axum::{body::Body as AxumBody, body::HttpBody, http::Request as HttpRequest, Router};
use http::Uri;
use tower_service::Service;
use url::Url;
use vercel_runtime::{run as vercel_run, Body, Error, Request, Response};
pub async fn run(app: Router) -> Result<(), Error> {
let handler = |mut req: Request| {
let mut app = app.clone();
async move {
let url = Url::parse(&req.uri().to_string()).unwrap();
let path = url
.query_pairs()
.find_map(|(k, v)| (k == "path").then_some(v))
.unwrap();
let new_path = format!("/{}?{}", path, req.uri().query().unwrap_or_default())
.parse()
.unwrap();
let mut uri = req.uri().clone().into_parts();
let path_and_query = uri.path_and_query.as_mut().unwrap();
*path_and_query = new_path;
*req.uri_mut() = Uri::from_parts(uri).unwrap();
let (req_parts, req_body) = req.into_parts();
let req_body = req_body.deref().to_owned();
let req = HttpRequest::from_parts(req_parts, AxumBody::from(req_body));
let initial_response = app.call(req).await?;
let (parts, mut initial_body) = initial_response.into_parts();
let mut buffer = Vec::new();
while let Some(bytes) = initial_body.data().await {
let bytes = bytes?;
buffer.extend(bytes);
}
let final_response = Response::from_parts(parts, Body::Binary(buffer));
Ok(final_response)
}
};
vercel_run(handler).await
}