From d89afd18dcd3346600c0b9a7af2caac07c518ca7 Mon Sep 17 00:00:00 2001
From: ErrorNoInternet <errornointernet@envs.net>
Date: Tue, 18 Mar 2025 17:24:59 -0400
Subject: [PATCH] feat!: print newlines properly

---
 src/http.rs       | 37 ++++++++++++++++++++-----------------
 src/lua/mod.rs    | 23 +++++++++++++++++++++--
 src/matrix/bot.rs | 16 ++++++++--------
 3 files changed, 49 insertions(+), 27 deletions(-)

diff --git a/src/http.rs b/src/http.rs
index 759510e..83aaf65 100644
--- a/src/http.rs
+++ b/src/http.rs
@@ -12,27 +12,30 @@ pub async fn serve(
     request: Request<Incoming>,
     state: State,
 ) -> Result<Response<BoxBody<Bytes, Error>>, Error> {
-    macro_rules! handle_code {
-        ($handler:ident) => {
-            match std::str::from_utf8(&request.into_body().collect().await?.to_bytes()) {
-                Ok(code) => Response::new(full(format!(
-                    "{:#?}",
-                    $handler(&state.lua, code, None).await
-                ))),
-                Err(error) => status_code_response(
-                    StatusCode::BAD_REQUEST,
-                    full(format!("invalid utf-8 data received: {error:?}")),
-                ),
-            }
-        };
-    }
-
     Ok(match (request.method(), request.uri().path()) {
         (&Method::POST, "/reload") => {
             Response::new(full(format!("{:#?}", reload(&state.lua, None))))
         }
-        (&Method::POST, "/eval") => handle_code!(eval),
-        (&Method::POST, "/exec") => handle_code!(exec),
+        (&Method::POST, "/eval") => match eval(
+            &state.lua,
+            &String::from_utf8_lossy(&request.into_body().collect().await?.to_bytes()),
+            None,
+        )
+        .await
+        {
+            Ok(value) => status_code_response(StatusCode::OK, full(value.to_string())),
+            Err(error) => status_code_response(StatusCode::BAD_REQUEST, full(error.to_string())),
+        },
+        (&Method::POST, "/exec") => match exec(
+            &state.lua,
+            &String::from_utf8_lossy(&request.into_body().collect().await?.to_bytes()),
+            None,
+        )
+        .await
+        {
+            Ok(()) => status_code_response(StatusCode::OK, empty()),
+            Err(error) => status_code_response(StatusCode::BAD_REQUEST, full(error.to_string())),
+        },
         (&Method::GET, "/ping") => Response::new(full("pong!")),
         _ => status_code_response(StatusCode::NOT_FOUND, empty()),
     })
diff --git a/src/lua/mod.rs b/src/lua/mod.rs
index bf95bfc..6c8048d 100644
--- a/src/lua/mod.rs
+++ b/src/lua/mod.rs
@@ -15,10 +15,12 @@ pub mod matrix;
 
 use crate::{ListenerMap, build_info::built};
 use mlua::{Lua, Table};
-use std::io;
+use std::{
+    fmt::{self, Display, Formatter},
+    io,
+};
 
 #[derive(Debug)]
-#[allow(dead_code)]
 pub enum Error {
     CreateEnv(mlua::Error),
     EvalChunk(mlua::Error),
@@ -28,6 +30,23 @@ pub enum Error {
     ReadFile(io::Error),
 }
 
+impl Display for Error {
+    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
+        write!(
+            formatter,
+            "{}",
+            match self {
+                Error::CreateEnv(error) => format!("failed to create environment: {error}"),
+                Error::EvalChunk(error) => format!("failed to evaluate chunk: {error}"),
+                Error::ExecChunk(error) => format!("failed to execute chunk: {error}"),
+                Error::LoadChunk(error) => format!("failed to load chunk: {error}"),
+                Error::MissingPath(error) => format!("failed to get SCRIPT_PATH global: {error}"),
+                Error::ReadFile(error) => format!("failed to read script file: {error}"),
+            }
+        )
+    }
+}
+
 pub fn register_globals(
     lua: &Lua,
     globals: &Table,
diff --git a/src/matrix/bot.rs b/src/matrix/bot.rs
index cb47f8a..9b3d669 100644
--- a/src/matrix/bot.rs
+++ b/src/matrix/bot.rs
@@ -49,16 +49,16 @@ pub async fn on_regular_room_message(
         match split.0.unwrap_or(body).to_lowercase().as_str() {
             "reload" => output = Some(format!("{:#?}", lua::reload(&ctx.state.lua, None))),
             "eval" if let Some(code) = code => {
-                output = Some(format!(
-                    "{:#?}",
-                    lua::eval(&ctx.state.lua, code, None).await
-                ));
+                output = Some(match lua::eval(&ctx.state.lua, code, None).await {
+                    Ok(value) => value.to_string(),
+                    Err(error) => error.to_string(),
+                });
             }
             "exec" if let Some(code) = code => {
-                output = Some(format!(
-                    "{:#?}",
-                    lua::exec(&ctx.state.lua, code, None).await
-                ));
+                output = Some(match lua::exec(&ctx.state.lua, code, None).await {
+                    Ok(()) => String::from("ok"),
+                    Err(error) => error.to_string(),
+                });
             }
             "ping" => {
                 room.send(RoomMessageEventContent::text_plain("pong!"))