diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/handler.rs | 12 | ||||
| -rw-r--r-- | src/handler/lua.rs | 75 | ||||
| -rw-r--r-- | src/main.rs | 1 |
3 files changed, 87 insertions, 1 deletions
diff --git a/src/handler.rs b/src/handler.rs index 45dc879..eb4d64a 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -1,8 +1,13 @@ +mod lua; mod staticfile; use mlua::{FromLua, Value}; -use crate::{handler::staticfile::StaticFile, request::Request, response::Response}; +use crate::{ + handler::{lua::LuaResponse, staticfile::StaticFile}, + request::Request, + response::Response, +}; pub trait Handle { fn handle(self, request: Request) -> impl Future<Output = Result<Response, Error>>; @@ -20,6 +25,7 @@ pub enum Error { #[derive(Debug)] pub enum Handler { StaticFile(StaticFile), + Lua(LuaResponse), } impl FromLua for Handler { @@ -30,6 +36,10 @@ impl FromLua for Handler { Value::Table(table.clone()), lua, )?)), + "lua" => Ok(Self::Lua(LuaResponse::from_lua( + Value::Table(table.clone()), + lua, + )?)), _ => Err(mlua::Error::runtime("unknown handler")), }, _ => Err(mlua::Error::runtime("expected table")), 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")), + } + } +} diff --git a/src/main.rs b/src/main.rs index 3d69f36..6d89a0d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -83,6 +83,7 @@ async fn handle(handlers: Table, request: Request) -> Result<Response, HandleErr match handler { Handler::StaticFile(staticfile) => Ok(staticfile.handle(request).await?), + Handler::Lua(lua_response) => Ok(lua_response.handle(request).await?), } } |
