Something went wrong. Try again.
🦦 a tiny cute lua web framework
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102const std = @import("std");
const fern = @import("fern");const zlua = @import("zlua");const Lua = zlua.Lua;
const maivi = @import("../root.zig");
pub fn lua_opendisplay(l: *Lua) !i32 { l.createTable(0, 2);
l.pushFunction(zlua.wrap(elem)); l.setField(-2, "elem");
l.pushFunction(zlua.wrap(attr)); l.setField(-2, "attr");
return 1;}
pub fn elem(l: *Lua) !i32 { if (l.isFunction(-1)) { try maivi.lua.pcall(l, .{ .results = 1 }); return try elem(l); } if (l.isTable(-1)) { return try recursive_concat(l, null); } if (l.isBoolean(-1)) { const str = switch (l.toBoolean(-1)) { true => "true", false => "false", }; _ = l.pushString(str); return 1; } l.pushValue(-1); _ = try l.toString(-1); return 1;}
pub fn attr(l: *Lua) !i32 { if (l.isTable(-1)) { return try recursive_concat(l, " "); } if (l.isBoolean(-1)) { const str = switch (l.toBoolean(-1)) { true => "true", false => "false", }; _ = l.pushString(str); return 1; } l.pushValue(-1); _ = try l.toString(-1); return 1;}
const Error = error{ ExpectedString, ExpectedTable } || error{ LuaRuntime, LuaMsgHandler } || std.mem.Allocator.Error;fn recursive_concat(l: *Lua, sep: ?[]const u8) Error!i32 { var arena: std.heap.ArenaAllocator = .init(maivi.allocator); defer arena.deinit(); var allocator = arena.allocator();
const slices = blk: { l.pushValue(-1);
if (!l.isTable(-1)) return error.ExpectedTable;
var slices: std.ArrayList([]const u8) = try .initCapacity(maivi.allocator, 16); errdefer slices.deinit(maivi.allocator);
l.pushNil(); // stack now contains: -1 => nil; -2 => table while (l.next(-2)) { // stack now contains: -1 => value; -2 => key; -3 => table _ = try elem(l); // stack now contains: -1 => value (parsed); -2 => value; -3 => key; -4 => table const vz = try l.toString(-1); const v = try allocator.dupe(u8, vz); try slices.append(maivi.allocator, v); // pop value + copy, leaving original key l.pop(2); // stack now contains: -1 => key; -2 => table }
l.pop(1);
break :blk try slices.toOwnedSlice(maivi.allocator); }; defer maivi.allocator.free(slices);
const str = if (sep) |s| try std.mem.join(maivi.allocator, s, slices) else try std.mem.concat(maivi.allocator, u8, slices); defer maivi.allocator.free(str); _ = l.pushString(str);
return 1;}