diff options
| author | John Turner <jturner.usa@gmail.com> | 2026-03-05 00:52:03 -0500 |
|---|---|---|
| committer | John Turner <jturner.usa@gmail.com> | 2026-03-05 00:52:03 -0500 |
| commit | 92e8d4947de614a67fed6709a59365de98705b35 (patch) | |
| tree | 981213f1ed73c88834f9ec3fe7c9b1b8f3e19211 /src/handler | |
| parent | 583a62c4a2ac6137134d50f70ff8ad546ac4b2a1 (diff) | |
| download | httpd-92e8d4947de614a67fed6709a59365de98705b35.tar.gz | |
impl Lua handler
Diffstat (limited to 'src/handler')
| -rw-r--r-- | src/handler/lua.rs | 75 |
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")), + } + } +} |
