chore: refactor format serialization API

The inconsistently named `cg.toJSON` has been renamed to
`cg.fmt.json.serialize`. The code has also been restructured to fit more
formats in the future.
This commit is contained in:
LordMZTE 2024-07-09 23:22:12 +02:00
parent 5a88ad31cf
commit 488a64809d
Signed by untrusted user: LordMZTE
GPG key ID: B64802DC33A64FF6
7 changed files with 62 additions and 36 deletions

View file

@ -144,14 +144,14 @@ pub fn run() !void {
libcg.c.lua_getfield(l, -1, "opt");
if (arg.positionals.len == 0) {
try libcg.json.luaToJSON(l, &wstream);
try libcg.format.formats.json.luaToJSON(l, &wstream);
libcg.c.lua_pop(l, 1);
} else {
try wstream.beginObject();
for (arg.positionals) |opt| {
try wstream.objectField(opt);
libcg.c.lua_getfield(l, -1, opt);
try libcg.json.luaToJSON(l, &wstream);
try libcg.format.formats.json.luaToJSON(l, &wstream);
}
libcg.c.lua_pop(l, 2);
try wstream.endObject();

View file

@ -575,7 +575,7 @@ fn generateOptsJSON(self: *FileSystem) ![]const u8 {
libcg.c.lua_getglobal(self.l, "cg");
libcg.c.lua_getfield(self.l, -1, "opt");
try libcg.json.luaToJSON(self.l, &wstream);
try libcg.format.formats.json.luaToJSON(self.l, &wstream);
return try buf.toOwnedSlice();
}

16
libcg/format.zig Normal file
View file

@ -0,0 +1,16 @@
const std = @import("std");
const ffi = @import("ffi.zig");
const c = ffi.c;
pub const formats = struct {
pub const json = @import("format/json.zig");
};
pub fn pushFmtTable(l: *c.lua_State) void {
c.lua_createtable(l, 0, @typeInfo(formats).Struct.decls.len);
inline for (@typeInfo(formats).Struct.decls) |decl| {
@field(formats, decl.name).luaPush(l);
c.lua_setfield(l, -2, decl.name);
}
}

View file

@ -1,9 +1,17 @@
//! Tools for serialization of Lua values to JSON
//! Used by the --json-opt flag
const std = @import("std");
const ffi = @import("ffi.zig");
const ffi = @import("../ffi.zig");
const c = ffi.c;
const luaapi = @import("../luaapi.zig");
pub fn luaPush(l: *c.lua_State) void {
c.lua_createtable(l, 0, 1);
c.lua_pushcfunction(l, ffi.luaFunc(lSerialize));
c.lua_setfield(l, -2, "serialize");
}
/// Writes a lua object to the stream. stream must be a json.WriteStream
pub fn luaToJSON(l: *c.lua_State, stream: anytype) !void {
const ty = c.lua_type(l, -1);
@ -71,3 +79,29 @@ pub fn luaToJSON(l: *c.lua_State, stream: anytype) !void {
else => unreachable,
}
}
fn lSerialize(l: *c.lua_State) !c_int {
c.luaL_checkany(l, 1);
const pretty = if (c.lua_gettop(l) >= 2) c.lua_toboolean(l, 2) != 0 else false;
const state = luaapi.getState(l);
// If you're doing more than 16KiB of JSON, open an issue
// and bring a VERY good explanation with you :D
var buf: [1024 * 16]u8 = undefined;
var fbs = std.io.fixedBufferStream(&buf);
var wstream = std.json.WriteStream(@TypeOf(fbs.writer()), .assumed_correct).init(
state.files.allocator,
fbs.writer(),
.{ .whitespace = if (pretty) .indent_2 else .minified },
);
defer wstream.deinit();
c.lua_pushvalue(l, 1);
try @import("json.zig").luaToJSON(l, &wstream);
const written = fbs.getWritten();
c.lua_pushlstring(l, written.ptr, written.len);
return 1;
}

View file

@ -1,6 +1,8 @@
const std = @import("std");
const ffi = @import("ffi.zig");
const c = ffi.c;
const format = @import("format.zig");
const luagen = @import("luagen.zig");
const TemplateCode = luagen.TemplateCode;
@ -92,12 +94,12 @@ pub fn initLuaState(cgstate: *CgState) !*c.lua_State {
c.lua_pushcfunction(l, ffi.luaFunc(lOnDone));
c.lua_setfield(l, -2, "onDone");
c.lua_pushcfunction(l, ffi.luaFunc(lToJSON));
c.lua_setfield(l, -2, "toJSON");
c.lua_pushcfunction(l, ffi.luaFunc(lFileIter));
c.lua_setfield(l, -2, "fileIter");
format.pushFmtTable(l);
c.lua_setfield(l, -2, "fmt");
// add cg table to globals
c.lua_setglobal(l, "cg");
@ -503,32 +505,6 @@ fn lOnDone(l: *c.lua_State) !c_int {
return 0;
}
fn lToJSON(l: *c.lua_State) !c_int {
c.luaL_checkany(l, 1);
const pretty = if (c.lua_gettop(l) >= 2) c.lua_toboolean(l, 2) != 0 else false;
const state = getState(l);
// If you're doing more than 16KiB of JSON, open an issue
// and bring a VERY good explanation with you :D
var buf: [1024 * 16]u8 = undefined;
var fbs = std.io.fixedBufferStream(&buf);
var wstream = std.json.WriteStream(@TypeOf(fbs.writer()), .assumed_correct).init(
state.files.allocator,
fbs.writer(),
.{ .whitespace = if (pretty) .indent_2 else .minified },
);
defer wstream.deinit();
c.lua_pushvalue(l, 1);
try @import("json.zig").luaToJSON(l, &wstream);
const written = fbs.getWritten();
c.lua_pushlstring(l, written.ptr, written.len);
return 1;
}
fn lFileIter(l: *c.lua_State) !c_int {
const state = getState(l);

View file

@ -2,7 +2,7 @@ const std = @import("std");
pub const c = ffi.c;
pub const ffi = @import("ffi.zig");
pub const json = @import("json.zig");
pub const format = @import("format.zig");
pub const luaapi = @import("luaapi.zig");
pub const luagen = @import("luagen.zig");

View file

@ -133,7 +133,7 @@ Example:
.B cg.onDone(function(errors) print(\(dqHad errors: \(dq .. tostring(errors)) end)
.TP
.B cg.toJSON(value[, pretty])
.B cg.fmt.json.serialize(value[, pretty])
Convert an arbitrary lua value to JSON and return that as a string. The JSON will be minified by
default unless
.IR pretty \ is \ true .
@ -144,7 +144,7 @@ will be serialized as
.IR null .
Example:
.B local json = cg.toJSON({ x = \(dqy\(dq }) -- '{\(dqx\(dq: \(dqy\(dq}'
.B local json = cg.fmt.json.serialize({ x = \(dqy\(dq }) -- '{\(dqx\(dq: \(dqy\(dq}'
.TP
.B cg.fileIter()