From e97bba72ebe3850a819796c0718441b8d6562297 Mon Sep 17 00:00:00 2001 From: Duckonaut Date: Wed, 4 Nov 2026 12:35:04 +0100 Subject: update: update dependencies, move to mlua --- src/error.rs | 6 +- src/luax/lexer.rs | 12 ++-- src/luax/mod.rs | 143 +++++++++++++++++++---------------------- src/luax/tests/preprocessor.rs | 2 +- src/main.rs | 14 ++-- src/server.rs | 30 ++++----- 6 files changed, 95 insertions(+), 112 deletions(-) (limited to 'src') diff --git a/src/error.rs b/src/error.rs index fabe012..6eb148e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -32,7 +32,7 @@ impl Display for LuaXError { #[derive(Debug)] pub enum ReluaxError { LuaX(LuaXError), - Lua(rlua::Error), + Lua(mlua::Error), Server(String), } @@ -54,8 +54,8 @@ impl From for ReluaxError { } } -impl From for ReluaxError { - fn from(err: rlua::Error) -> Self { +impl From for ReluaxError { + fn from(err: mlua::Error) -> Self { ReluaxError::Lua(err) } } diff --git a/src/luax/lexer.rs b/src/luax/lexer.rs index c075b3a..c304412 100644 --- a/src/luax/lexer.rs +++ b/src/luax/lexer.rs @@ -23,10 +23,6 @@ macro_rules! try_all_paths { }; } -pub trait TokenProducer { - fn next(&mut self) -> Option; -} - #[derive(Debug)] pub struct Lexer<'s> { src: &'s str, @@ -297,18 +293,18 @@ impl<'s> Lexer<'s> { } fn number(&mut self) -> TokenizeResult<'s> { - if !self.current.map_or(false, |c| c.is_numeric()) { + if !self.current.is_some_and(|c| c.is_numeric()) { return TokenizeResult::None; } let start = self.current_pos_in_bytes; - while self.current.map_or(false, |c| c.is_numeric()) { + while self.current.is_some_and(|c| c.is_numeric()) { self.advance(); } if self.match_char('.') { - while self.current.map_or(false, |c| c.is_numeric()) { + while self.current.is_some_and(|c| c.is_numeric()) { self.advance(); } } @@ -317,7 +313,7 @@ impl<'s> Lexer<'s> { if self.match_char('-') || self.match_char('+') { self.advance(); } - while self.current.map_or(false, |c| c.is_numeric()) { + while self.current.is_some_and(|c| c.is_numeric()) { self.advance(); } } diff --git a/src/luax/mod.rs b/src/luax/mod.rs index 994b80e..13afd88 100644 --- a/src/luax/mod.rs +++ b/src/luax/mod.rs @@ -1,6 +1,6 @@ use std::path::Path; -use rlua::Lua; +use mlua::Lua; use crate::{error::LuaXError, Result}; @@ -10,15 +10,15 @@ mod preprocessor; mod tests; mod tokens; -pub fn table_to_html(table: rlua::Table, f: &mut W) -> Result<()> { +pub fn table_to_html(table: mlua::Table, f: &mut W) -> Result<()> { let tag_name: Option = table.get("tag").unwrap(); if tag_name.is_none() { // we might be in a list - for child in table.sequence_values::() { + for child in table.sequence_values::() { match child? { - rlua::Value::Table(child) => table_to_html(child, f)?, - rlua::Value::String(s) => write!(f, "{}", s.to_str()?)?, + mlua::Value::Table(child) => table_to_html(child, f)?, + mlua::Value::String(s) => write!(f, "{}", s.to_str()?)?, _ => return Err(LuaXError::NonTableChildren.into()), } } @@ -31,7 +31,7 @@ pub fn table_to_html(table: rlua::Table, f: &mut W) -> Result write!(f, "<{}", type_name)?; let mut children = None; let mut attrs = None; - for pair in table.pairs::() { + for pair in table.pairs::() { let (key, value) = pair?; if key == "tag" { continue; @@ -46,8 +46,8 @@ pub fn table_to_html(table: rlua::Table, f: &mut W) -> Result } } if let Some(attrs) = attrs { - if let rlua::Value::Table(attrs) = attrs { - for pair in attrs.pairs::() { + if let mlua::Value::Table(attrs) = attrs { + for pair in attrs.pairs::() { let (key, value) = pair?; write!(f, " {}=\"{}\"", key, value.to_str()?)?; } @@ -58,13 +58,13 @@ pub fn table_to_html(table: rlua::Table, f: &mut W) -> Result write!(f, ">")?; if let Some(children) = children { - if let rlua::Value::Table(children) = children { - for child in children.sequence_values::() { + if let mlua::Value::Table(children) = children { + for child in children.sequence_values::() { match child? { - rlua::Value::Table(child) => table_to_html(child, f)?, - rlua::Value::String(s) => write!(f, "{}", s.to_str()?)?, - rlua::Value::Boolean(b) => write!(f, "{}", b)?, - rlua::Value::Number(n) => write!(f, "{}", n)?, + mlua::Value::Table(child) => table_to_html(child, f)?, + mlua::Value::String(s) => write!(f, "{}", s.to_str()?)?, + mlua::Value::Boolean(b) => write!(f, "{}", b)?, + mlua::Value::Number(n) => write!(f, "{}", n)?, _ => return Err(LuaXError::NonTableChildren.into()), } } @@ -78,10 +78,10 @@ pub fn table_to_html(table: rlua::Table, f: &mut W) -> Result Ok(()) } -pub fn table_to_json(table: rlua::Table, f: &mut W) -> Result<()> { +pub fn table_to_json(table: mlua::Table, f: &mut W) -> Result<()> { let mut first = true; write!(f, "{{")?; - for pair in table.pairs::() { + for pair in table.pairs::() { let (key, value) = pair?; if !first { write!(f, ",")?; @@ -89,11 +89,11 @@ pub fn table_to_json(table: rlua::Table, f: &mut W) -> Result first = false; write!(f, "\"{}\":", key)?; match value { - rlua::Value::Table(t) => table_to_json(t, f)?, - rlua::Value::String(s) => write!(f, "\"{}\"", s.to_str()?)?, - rlua::Value::Boolean(b) => write!(f, "{}", b)?, - rlua::Value::Number(n) => write!(f, "{}", n)?, - rlua::Value::Nil => write!(f, "null")?, + mlua::Value::Table(t) => table_to_json(t, f)?, + mlua::Value::String(s) => write!(f, "\"{}\"", s.to_str()?)?, + mlua::Value::Boolean(b) => write!(f, "{}", b)?, + mlua::Value::Number(n) => write!(f, "{}", n)?, + mlua::Value::Nil => write!(f, "null")?, _ => return Err(LuaXError::NonJsonType.into()), } } @@ -161,33 +161,29 @@ pub fn prepare_lua(dev_mode: bool) -> Result { // create a table called "reluax" with common utility functions // and put it in the global scope - lua.context(|ctx| -> Result<()> { - let reluax = ctx.create_table()?; - - let url_matches = ctx.create_function(utils::url_matches)?; - reluax.set("url_matches", url_matches)?; - let url_extract = ctx.create_function(utils::url_extract)?; - reluax.set("url_extract", url_extract)?; - let html = ctx.create_function(utils::wrap_html)?; - reluax.set("html", html)?; - let html_page = ctx.create_function(utils::wrap_html_page)?; - reluax.set("html_page", html_page)?; - let json = ctx.create_function(utils::wrap_json)?; - reluax.set("json", json)?; - let headers = ctx.create_function(utils::wrap_headers)?; - reluax.set("headers", headers)?; - reluax.set("dev_mode", dev_mode)?; - - ctx.globals().set("reluax", reluax)?; - - Ok(()) - })?; + let reluax = lua.create_table()?; + + let url_matches = lua.create_function(utils::url_matches)?; + reluax.set("url_matches", url_matches)?; + let url_extract = lua.create_function(utils::url_extract)?; + reluax.set("url_extract", url_extract)?; + let html = lua.create_function(utils::wrap_html)?; + reluax.set("html", html)?; + let html_page = lua.create_function(utils::wrap_html_page)?; + reluax.set("html_page", html_page)?; + let json = lua.create_function(utils::wrap_json)?; + reluax.set("json", json)?; + let headers = lua.create_function(utils::wrap_headers)?; + reluax.set("headers", headers)?; + reluax.set("dev_mode", dev_mode)?; + + lua.globals().set("reluax", reluax)?; Ok(lua) } mod utils { - use rlua::{Context, Result, Table}; + use mlua::{Lua, Result, Table}; /// Check if a path matches a pattern /// @@ -202,7 +198,7 @@ mod utils { /// /// This function only checks if the path matches the pattern, it does not /// capture any values. - pub fn url_matches(_: Context<'_>, (pattern, path): (String, String)) -> Result { + pub fn url_matches(_: &Lua, (pattern, path): (String, String)) -> Result { let mut path = path.chars(); let mut pattern = pattern.chars(); @@ -253,7 +249,7 @@ mod utils { /// - `{name}` matches anything except `/` and captures the value as `name` /// /// This function will return a table with the captured values. - pub fn url_extract(ctx: Context<'_>, (pattern, path): (String, String)) -> Result { + pub fn url_extract(ctx: &Lua, (pattern, path): (String, String)) -> Result
{ let mut path = path.chars(); let mut pattern = pattern.chars(); @@ -303,35 +299,32 @@ mod utils { } /// Wrap a table in a table to signal that it should be rendered as HTML - pub fn wrap_html<'lua>(_: Context<'lua>, table: Table<'lua>) -> Result> { + pub fn wrap_html(_: &Lua, table: Table) -> Result
{ table.set("type", "html")?; Ok(table) } /// Wrap a table in a table to signal that it should be rendered as a full HTML page - pub fn wrap_html_page<'lua>(_: Context<'lua>, table: Table<'lua>) -> Result> { + pub fn wrap_html_page(_: &Lua, table: Table) -> Result
{ table.set("type", "html-page")?; Ok(table) } /// Wrap a table in a table to signal that it should be rendered as JSON - pub fn wrap_json<'lua>(_: Context<'lua>, table: Table<'lua>) -> Result> { + pub fn wrap_json(_: &Lua, table: Table) -> Result
{ table.set("type", "json")?; Ok(table) } /// Wrap a table to add headers to the response - pub fn wrap_headers<'lua>( - _: Context<'lua>, - (table, headers): (Table<'lua>, Table<'lua>), - ) -> Result> { + pub fn wrap_headers(_: &Lua, (table, headers): (Table, Table)) -> Result
{ table.set("headers", headers)?; Ok(table) } #[cfg(test)] mod tests { - use rlua::Lua; + use mlua::Lua; #[test] fn url_matches() { @@ -354,9 +347,8 @@ mod utils { let lua = Lua::new(); for (pattern, path, expected) in cases { - let res: bool = lua - .context(|ctx| super::url_matches(ctx, (pattern.to_string(), path.to_string()))) - .unwrap(); + let res: bool = + super::url_matches(&lua, (pattern.to_string(), path.to_string())).unwrap(); if res != expected { if expected { panic!("expected {} to match {}", path, pattern); @@ -392,27 +384,24 @@ mod utils { for (pattern, path, mut expected) in cases { expected.sort_by_key(|(k, _)| k.to_owned()); - lua.context(|ctx| { - let res = - super::url_extract(ctx, (pattern.to_string(), path.to_string())).unwrap(); - let mut res_vec = Vec::new(); - for pair in res.pairs::() { - let (key, value) = pair.unwrap(); - res_vec.push((key, value)); - } - res_vec.sort_by_key(|(k, _)| k.clone()); - - let equal = res_vec - .iter() - .zip(expected.iter()) - .all(|((k1, v1), (k2, v2))| k1 == k2 && v1 == v2); - if !equal { - panic!( - "expected {:?} to be {:?} for pattern {} and path {}", - res_vec, expected, pattern, path - ); - } - }) + let res = super::url_extract(&lua, (pattern.to_string(), path.to_string())).unwrap(); + let mut res_vec = Vec::new(); + for pair in res.pairs::() { + let (key, value) = pair.unwrap(); + res_vec.push((key, value)); + } + res_vec.sort_by_key(|(k, _)| k.clone()); + + let equal = res_vec + .iter() + .zip(expected.iter()) + .all(|((k1, v1), (k2, v2))| k1 == k2 && v1 == v2); + if !equal { + panic!( + "expected {:?} to be {:?} for pattern {} and path {}", + res_vec, expected, pattern, path + ); + } } } } diff --git a/src/luax/tests/preprocessor.rs b/src/luax/tests/preprocessor.rs index 9411126..d6540ff 100644 --- a/src/luax/tests/preprocessor.rs +++ b/src/luax/tests/preprocessor.rs @@ -1,7 +1,7 @@ use crate::luax::{lexer::Lexer, tokens::Token, *}; use color_eyre::Result; -fn tokenize(input: &str) -> Result> { +fn tokenize(input: &str) -> Result>> { let mut lexer = Lexer::new(input); let mut tokens = Vec::new(); diff --git a/src/main.rs b/src/main.rs index e9e0472..b39f26d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -261,16 +261,14 @@ async fn ensure_entry_point() -> Result<()> { async fn serve(dev_mode: bool, port: u16, public_dir: Option) -> Result<()> { println!("📦 Building Lua state..."); let lua = luax::prepare_lua(dev_mode)?; - lua.context(|ctx| -> Result<()> { - let entry_table: rlua::Table = ctx.load("require('reluax')").eval()?; - let project_name: Option = entry_table.get("name")?; - if let Some(name) = project_name { - println!("🌴 App name: {}", name.bright_yellow()); - } + let entry_table: mlua::Table = lua.load("require('reluax')").eval()?; + let project_name: Option = entry_table.get("name")?; + + if let Some(name) = project_name { + println!("🌴 App name: {}", name.bright_yellow()); + } - Ok(()) - })?; println!("🛫 Starting server on port {}...", port); server::Server::serve(lua, port, public_dir).await } diff --git a/src/server.rs b/src/server.rs index f57bcdc..b6e8110 100644 --- a/src/server.rs +++ b/src/server.rs @@ -16,7 +16,7 @@ use tokio::net::TcpListener; use crate::error::ReluaxError; use crate::luax::{table_to_html, table_to_json}; use color_eyre::Result; -use rlua::Lua; +use mlua::Lua; pub struct Server { port: u16, @@ -88,10 +88,10 @@ fn mk_file_response(path: PathBuf) -> Result>> { .body(Full::new(Bytes::from(bytes)))?) } -fn decode_luax_response(status: StatusCode, t: rlua::Table) -> Result>> { - let lua_headers: Option = t.get("headers")?; +fn decode_luax_response(status: StatusCode, t: mlua::Table) -> Result>> { + let lua_headers: Option = t.get("headers")?; - let (response_body, mime_type) = if t.contains_key("type")? { + let (response_body, mime_type) = if t.contains_key("type")? { let ty: String = t.get("type")?; let mime_type: Option = t.get("mime_type")?; @@ -172,8 +172,8 @@ impl State { ) -> Result>> { let lua = lua.lock().unwrap(); - let res = lua.context(|ctx| -> Result>> { - let manifest: rlua::Result = ctx.load("require('reluax')").eval(); + let res = { + let manifest: mlua::Result = lua.load("require('reluax')").eval(); let manifest = match manifest { Ok(m) => m, @@ -187,16 +187,16 @@ impl State { } }; - let route: rlua::Function = manifest.get("route")?; + let route: mlua::Function = manifest.get("route")?; let method = method.as_str(); - let body: rlua::String = ctx.create_string(&body.to_bytes().to_vec())?; - let lua_headers: rlua::Table = ctx.create_table()?; + let body: mlua::LuaString = lua.create_string(body.to_bytes())?; + let lua_headers: mlua::Table = lua.create_table()?; for (k, v) in headers { lua_headers.set(k, v)?; } - let res: rlua::Result<(rlua::Integer, rlua::Value)> = + let res: mlua::Result<(mlua::Integer, mlua::Value)> = route.call((path.clone(), method, lua_headers, body)); let res = match res { @@ -227,13 +227,13 @@ impl State { } match res.1 { - rlua::Value::String(s) => mk_response(status, s.to_str()?.to_string()), - rlua::Value::Table(t) => decode_luax_response(status, t), - rlua::Value::Nil => Err(ReluaxError::Server("No route found".to_string()).into()), - rlua::Value::Error(e) => Err(ReluaxError::Lua(e).into()), + mlua::Value::String(s) => mk_response(status, s.to_str()?.to_string()), + mlua::Value::Table(t) => decode_luax_response(status, t), + mlua::Value::Nil => Err(ReluaxError::Server("No route found".to_string()).into()), + mlua::Value::Error(e) => Err(ReluaxError::Lua(*e).into()), _ => Err(ReluaxError::Server("Route returned invalid type".to_string()).into()), } - })?; + }?; Ok(res) } -- cgit v1.3.1