64 lines
1.9 KiB
Rust

use crate::{
State,
lua::{eval, exec, reload},
};
use http_body_util::{BodyExt, Empty, Full, combinators::BoxBody};
use hyper::{
Error, Method, Request, Response, StatusCode,
body::{Bytes, Incoming},
};
pub async fn serve(
request: Request<Incoming>,
state: State,
) -> Result<Response<BoxBody<Bytes, Error>>, Error> {
Ok(match (request.method(), request.uri().path()) {
(&Method::POST, "/reload") => {
Response::new(full(format!("{:#?}", reload(&state.lua, None))))
}
(&Method::POST, "/eval") => match eval(
&state.lua,
&String::from_utf8_lossy(&request.into_body().collect().await?.to_bytes()),
None,
)
.await
{
Ok(value) => status_code_response(StatusCode::OK, full(value.to_string())),
Err(error) => status_code_response(StatusCode::BAD_REQUEST, full(error.to_string())),
},
(&Method::POST, "/exec") => match exec(
&state.lua,
&String::from_utf8_lossy(&request.into_body().collect().await?.to_bytes()),
None,
)
.await
{
Ok(()) => status_code_response(StatusCode::OK, empty()),
Err(error) => status_code_response(StatusCode::BAD_REQUEST, full(error.to_string())),
},
(&Method::GET, "/ping") => Response::new(full("pong!")),
_ => status_code_response(StatusCode::NOT_FOUND, empty()),
})
}
fn status_code_response(
status_code: StatusCode,
bytes: BoxBody<Bytes, Error>,
) -> Response<BoxBody<Bytes, Error>> {
let mut response = Response::new(bytes);
*response.status_mut() = status_code;
response
}
fn full<T: Into<Bytes>>(chunk: T) -> BoxBody<Bytes, hyper::Error> {
Full::new(chunk.into())
.map_err(|never| match never {})
.boxed()
}
fn empty() -> BoxBody<Bytes, hyper::Error> {
Empty::<Bytes>::new()
.map_err(|never| match never {})
.boxed()
}