summaryrefslogtreecommitdiff
path: root/src/handler
diff options
context:
space:
mode:
authorJohn Turner <jturner.usa@gmail.com>2026-03-05 00:52:03 -0500
committerJohn Turner <jturner.usa@gmail.com>2026-03-05 00:52:03 -0500
commit92e8d4947de614a67fed6709a59365de98705b35 (patch)
tree981213f1ed73c88834f9ec3fe7c9b1b8f3e19211 /src/handler
parent583a62c4a2ac6137134d50f70ff8ad546ac4b2a1 (diff)
downloadhttpd-92e8d4947de614a67fed6709a59365de98705b35.tar.gz
impl Lua handler
Diffstat (limited to 'src/handler')
-rw-r--r--src/handler/lua.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/handler/lua.rs b/src/handler/lua.rs
new file mode 100644
index 0000000..377111f
--- /dev/null
+++ b/src/handler/lua.rs
@@ -0,0 +1,75 @@
+use std::{collections::HashMap, str::FromStr};
+
+use mlua::{FromLua, Lua, Value};
+
+use crate::{
+ handler::{self, Handle},
+ request::Request,
+ response::{Body, Response, Status},
+};
+
+#[derive(Debug, Clone)]
+pub struct LuaResponse {
+ content: Option<Vec<u8>>,
+ status: Status,
+ headers: HashMap<String, Vec<u8>>,
+}
+
+impl Handle for LuaResponse {
+ async fn handle(self, _: Request) -> Result<Response, handler::Error> {
+ Ok(Response::builder()
+ .status(self.status)
+ .headers(self.headers)
+ .body(match self.content {
+ Some(content) => Body::Buffer(content),
+ None => Body::Empty,
+ }))
+ }
+}
+
+impl FromLua for LuaResponse {
+ fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
+ match value {
+ Value::Table(table) => {
+ let content = match table.get("content")? {
+ Value::String(string) => Some(string.as_bytes().to_vec()),
+ _ => None,
+ };
+
+ let status = match table.get("status")? {
+ Value::String(string) => Status::from_str(&string.to_str()?).map_err(|e| {
+ mlua::Error::RuntimeError(format!(
+ "failed to parse status from string: {e}"
+ ))
+ })?,
+ Value::Integer(i) => Status::from_repr(i as usize).ok_or_else(|| {
+ mlua::Error::runtime(format!("failed to parse status from integer: {i}"))
+ })?,
+ _ => return Err(mlua::Error::runtime("invalid type when reading status")),
+ };
+
+ let headers: HashMap<String, Vec<u8>> = match table.get::<Value>("headers")? {
+ Value::Table(table) => {
+ let mut hashmap = HashMap::<String, Vec<u8>>::new();
+
+ for result in table.pairs() {
+ let (key, value): (String, mlua::BString) = result?;
+
+ hashmap.insert(key, value.to_vec());
+ }
+
+ hashmap
+ }
+ _ => HashMap::new(),
+ };
+
+ Ok(Self {
+ content,
+ status,
+ headers,
+ })
+ }
+ _ => Err(mlua::Error::runtime("expected table")),
+ }
+ }
+}