commit a09b25f7dd0b6d25c58646c1fcc34146e894bf4c
parent 81ee36dcbae6104b42a145c499c8ec60f1555d8b
Author: Christian Ermann <christianermann@gmail.com>
Date: Sun, 1 Mar 2026 17:01:42 -0800
Improve struct rendering
Diffstat:
| M | src/main.zig | | | 137 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- |
1 file changed, 129 insertions(+), 8 deletions(-)
diff --git a/src/main.zig b/src/main.zig
@@ -90,9 +90,25 @@ const PrimitiveType = enum {
@"array<float32>",
@"array<float64>",
+ pub fn isArray(self: PrimitiveType) bool {
+ return switch (self) {
+ .@"array<bool>" => true,
+ .@"array<string>" => true,
+ .@"array<uint16>" => true,
+ .@"array<uint32>" => true,
+ .@"array<uint64>" => true,
+ .@"array<usize>" => true,
+ .@"array<int16>" => true,
+ .@"array<int32>" => true,
+ .@"array<float32>" => true,
+ .@"array<float64>" => true,
+ else => false,
+ };
+ }
+
fn toString(self: PrimitiveType) []const u8 {
return switch (self) {
- .c_void => "c_void",
+ .c_void => "anyopaque",
.bool => "bool",
.nullable_string => "?[]const u8",
.string_with_default_empty => "[]const u8",
@@ -120,9 +136,34 @@ const PrimitiveType = enum {
};
}
+ fn toStringConst(self: PrimitiveType) ![]const u8 {
+ return switch (self) {
+ .@"array<bool>" => "[]const bool",
+ .@"array<string>" => "[]const []const u8",
+ .@"array<uint16>" => "[]const u16",
+ .@"array<uint32>" => "[]const u32",
+ .@"array<uint64>" => "[]const u64",
+ .@"array<usize>" => "[]const usize",
+ .@"array<int16>" => "[]const i16",
+ .@"array<int32>" => "[]const i32",
+ .@"array<float32>" => "[]const f32",
+ .@"array<float64>" => "[]const f64",
+ else => error.Unimplemented,
+ };
+ }
+
pub fn render(self: PrimitiveType, writer: anytype) !void {
try writer.writeAll(self.toString());
}
+
+ pub fn renderConst(self: PrimitiveType, writer: anytype) !void {
+ if (self.isArray()) {
+ try writer.writeAll(try self.toStringConst());
+ } else {
+ try writer.writeAll("const ");
+ try writer.writeAll(self.toString());
+ }
+ }
};
const ComplexType = union(enum) {
@@ -143,6 +184,13 @@ const ComplexType = union(enum) {
name: []const u8,
};
+ pub fn isArray(self: ComplexType) bool {
+ return switch (self) {
+ .single => false,
+ .array => true,
+ };
+ }
+
pub fn render(self: ComplexType, writer: anytype) !void {
switch (self) {
.single => |single| {
@@ -155,6 +203,19 @@ const ComplexType = union(enum) {
}
}
+ pub fn renderConst(self: ComplexType, writer: anytype) !void {
+ switch (self) {
+ .single => |single| {
+ try writer.writeAll("const ");
+ try snakeToPascal(single.name, writer);
+ },
+ .array => |array| {
+ try writer.writeAll("[]const ");
+ try snakeToPascal(array.name, writer);
+ },
+ }
+ }
+
pub fn parse(raw: []const u8) ?ComplexType {
var array = false;
var type_str = raw;
@@ -246,6 +307,14 @@ const Type = union(enum) {
complex: ComplexType,
callback: CallbackType,
+ pub fn isArray(self: Type) bool {
+ return switch (self) {
+ .primitive => |inner| inner.isArray(),
+ .complex => |inner| inner.isArray(),
+ .callback => false,
+ };
+ }
+
pub fn render(self: Type, writer: anytype) !void {
return switch (self) {
.primitive => |inner| inner.render(writer),
@@ -254,6 +323,14 @@ const Type = union(enum) {
};
}
+ pub fn renderConst(self: Type, writer: anytype) !void {
+ return switch (self) {
+ .primitive => |inner| inner.renderConst(writer),
+ .complex => |inner| inner.renderConst(writer),
+ .callback => error.Unimplemented,
+ };
+ }
+
pub fn jsonParse(
allocator: std.mem.Allocator,
source: anytype,
@@ -328,12 +405,26 @@ const ParameterType = struct {
type: Type,
passed_with_ownership: ?bool = null,
pointer: ?Pointer = null,
- optional: ?bool = null,
+ optional: bool = false,
default: ?DefaultValue = null,
fn render(self: ParameterType, writer: anytype) !void {
- try writer.print("{s}: ", .{ self.name });
- try self.type.render(writer);
+ try writer.writeAll(self.name);
+ try writer.writeAll(": ");
+ if (self.optional) {
+ try writer.writeAll("?");
+ }
+ if (self.pointer) |pointer| {
+ if (!self.type.isArray()) {
+ try writer.writeAll("*");
+ }
+ switch (pointer) {
+ .immutable => try self.type.renderConst(writer),
+ .mutable => try self.type.render(writer),
+ }
+ } else {
+ try self.type.render(writer);
+ }
}
};
@@ -465,26 +556,56 @@ const BitFlagEntry = struct {
value_combination: ?[][]const u8 = null,
};
+const StructType = enum {
+ extensible,
+ extensible_callback_arg,
+ extension,
+ standalone,
+};
+
const Struct = struct {
name: []const u8,
namespace: ?[]const u8 = null,
doc: []const u8,
- type: []const u8,
+ type: StructType,
extends: ?[][]const u8 = null,
free_members: ?bool = null,
members: ?[]ParameterType = null,
- fn render(self: Struct, writer: anytype) !void {
+ fn render(self: Struct, writer: anytype, indent: u32) !void {
+ try renderDoc(self, writer, indent);
+ try renderIndent(indent, writer);
try writer.writeAll("pub const ");
try snakeToPascal(self.name, writer);
try writer.writeAll(" = extern struct {\n");
+ switch (self.type) {
+ .extensible, .extensible_callback_arg => {
+ try renderIndent(indent + 1, writer);
+ try writer.writeAll("next: ?*const ChainedStruct = null,\n");
+ },
+ .extension => {
+ try renderIndent(indent + 1, writer);
+ try writer.writeAll("chain: ChainedStruct = .{\n");
+ try renderIndent(indent + 2, writer);
+ try writer.writeAll(".next = null,\n");
+ try renderIndent(indent + 2, writer);
+ try writer.writeAll(".struct_type = .");
+ try toLowercase(self.name, writer);
+ try writer.writeAll(",\n");
+ try renderIndent(indent + 1, writer);
+ try writer.writeAll("},\n");
+ },
+ .standalone => {},
+ }
if (self.members) |members| {
for (members) |member| {
- try writer.writeAll(" ");
+ try renderDoc(member, writer, indent + 1);
+ try renderIndent(indent + 1, writer);
try member.render(writer);
try writer.writeAll(",\n");
}
}
+ try renderIndent(indent, writer);
try writer.writeAll("};\n");
}
};
@@ -659,7 +780,7 @@ pub fn main() !void {
}
try stdout.writeAll("// structs\n");
for (parsed.value.structs) |obj| {
- try obj.render(stdout);
+ try obj.render(stdout, 0);
try stdout.writeAll("\n");
}
try stdout.writeAll("// callbacks\n");