From ce18078480b51ef665dd921bf0f87c7964cabcdf Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Thu, 16 Jan 2025 12:34:55 +0100 Subject: [PATCH] Better string handling --- common/space_lua/runtime.test.ts | 8 +++++- common/space_lua/runtime.ts | 45 +++++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/common/space_lua/runtime.test.ts b/common/space_lua/runtime.test.ts index 1d38cc50..0a6942bc 100644 --- a/common/space_lua/runtime.test.ts +++ b/common/space_lua/runtime.test.ts @@ -4,9 +4,10 @@ import { luaLen, LuaMultiRes, LuaStackFrame, + luaToString, } from "$common/space_lua/runtime.ts"; -Deno.test("Test Lua Rutime", () => { +Deno.test("Test Lua Rutime", async () => { // Test LuaMultires assertEquals(new LuaMultiRes([]).flatten().values, []); assertEquals(new LuaMultiRes([1, 2, 3]).flatten().values, [1, 2, 3]); @@ -42,4 +43,9 @@ Deno.test("Test Lua Rutime", () => { // Functions in objects luaVal = jsToLuaValue({ name: "Pete", first: (l: any[]) => l[0] }); assertEquals(luaVal.get("first").call(LuaStackFrame.lostFrame, [1, 2, 3]), 1); + + // Test luaToString + assertEquals(await luaToString(new Promise((resolve) => resolve(1))), "1"); + assertEquals(await luaToString({ a: 1 }), "{a = 1}"); + assertEquals(await luaToString([{ a: 1 }]), "{{a = 1}}"); }); diff --git a/common/space_lua/runtime.ts b/common/space_lua/runtime.ts index e61b8a6a..4bb9e7f0 100644 --- a/common/space_lua/runtime.ts +++ b/common/space_lua/runtime.ts @@ -678,15 +678,54 @@ export function luaTruthy(value: any): boolean { return true; } -export function luaToString(value: any): string | Promise { +export async function luaToString(value: any): Promise { if (value === null || value === undefined) { return "nil"; } + if (value instanceof Promise) { + return luaToString(await value); + } if (value.toStringAsync) { return value.toStringAsync(); } - if (value.toString) { - return value.toString(); + // Handle plain JavaScript objects in a Lua-like format + if (typeof value === "object") { + let result = "{"; + let first = true; + + // Handle arrays + if (Array.isArray(value)) { + for (const val of value) { + if (first) { + first = false; + } else { + result += ", "; + } + // Recursively stringify the value + const strVal = await luaToString(val); + result += strVal; + } + return result + "}"; + } + + // Handle objects + for (const [key, val] of Object.entries(value)) { + if (first) { + first = false; + } else { + result += ", "; + } + if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) { + result += `${key} = `; + } else { + result += `["${key}"] = `; + } + // Recursively stringify the value + const strVal = await luaToString(val); + result += strVal; + } + result += "}"; + return result; } return String(value); }