mirror of
https://github.com/lune-org/lune.git
synced 2025-04-03 18:10:54 +01:00
89 lines
2.9 KiB
Rust
89 lines
2.9 KiB
Rust
use std::str::FromStr;
|
|
|
|
use bstr::{BString, ByteSlice};
|
|
use http_body_util::Full;
|
|
use hyper::{
|
|
body::Bytes,
|
|
header::{HeaderName, HeaderValue},
|
|
HeaderMap, Response,
|
|
};
|
|
|
|
use mlua::prelude::*;
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub(super) enum LuaResponseKind {
|
|
PlainText,
|
|
Table,
|
|
}
|
|
|
|
pub(super) struct LuaResponse {
|
|
pub(super) kind: LuaResponseKind,
|
|
pub(super) status: u16,
|
|
pub(super) headers: HeaderMap,
|
|
pub(super) body: Option<Vec<u8>>,
|
|
}
|
|
|
|
impl LuaResponse {
|
|
pub(super) fn into_response(self) -> LuaResult<Response<Full<Bytes>>> {
|
|
Ok(match self.kind {
|
|
LuaResponseKind::PlainText => Response::builder()
|
|
.status(200)
|
|
.header("Content-Type", "text/plain")
|
|
.body(Full::new(Bytes::from(self.body.unwrap())))
|
|
.into_lua_err()?,
|
|
LuaResponseKind::Table => {
|
|
let mut response = Response::builder()
|
|
.status(self.status)
|
|
.body(Full::new(Bytes::from(self.body.unwrap_or_default())))
|
|
.into_lua_err()?;
|
|
response.headers_mut().extend(self.headers);
|
|
response
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
impl FromLua<'_> for LuaResponse {
|
|
fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
|
|
match value {
|
|
// Plain strings from the handler are plaintext responses
|
|
LuaValue::String(s) => Ok(Self {
|
|
kind: LuaResponseKind::PlainText,
|
|
status: 200,
|
|
headers: HeaderMap::new(),
|
|
body: Some(s.as_bytes().to_vec()),
|
|
}),
|
|
// Tables are more detailed responses with potential status, headers, body
|
|
LuaValue::Table(t) => {
|
|
let status: Option<u16> = t.get("status")?;
|
|
let headers: Option<LuaTable> = t.get("headers")?;
|
|
let body: Option<BString> = t.get("body")?;
|
|
|
|
let mut headers_map = HeaderMap::new();
|
|
if let Some(headers) = headers {
|
|
for pair in headers.pairs::<String, LuaString>() {
|
|
let (h, v) = pair?;
|
|
let name = HeaderName::from_str(&h).into_lua_err()?;
|
|
let value = HeaderValue::from_bytes(v.as_bytes()).into_lua_err()?;
|
|
headers_map.insert(name, value);
|
|
}
|
|
}
|
|
|
|
let body_bytes = body.map(|s| s.as_bytes().to_vec());
|
|
|
|
Ok(Self {
|
|
kind: LuaResponseKind::Table,
|
|
status: status.unwrap_or(200),
|
|
headers: headers_map,
|
|
body: body_bytes,
|
|
})
|
|
}
|
|
// Anything else is an error
|
|
value => Err(LuaError::FromLuaConversionError {
|
|
from: value.type_name(),
|
|
to: "NetServeResponse",
|
|
message: None,
|
|
}),
|
|
}
|
|
}
|
|
}
|