diff --git a/src/Class.zig b/src/Class.zig index d244335..15488c6 100644 --- a/src/Class.zig +++ b/src/Class.zig @@ -1,11 +1,7 @@ const std = @import("std"); const EnumFlags = @import("EnumFlags.zig").EnumFlags; - -pub const FieldInfo = @import("Class/FieldInfo.zig"); -pub const MethodInfo = @import("Class/MethodInfo.zig"); -pub const AttributeInfo = @import("Class/AttributeInfo.zig").AttributeInfo; -pub const ConstantPool = @import("Class/ConstantPool.zig"); +const Formatter = @import("Formatter.zig"); allocator: std.mem.Allocator, @@ -23,6 +19,11 @@ attributes: []AttributeInfo, const Self = @This(); +pub const FieldInfo = @import("Class/FieldInfo.zig"); +pub const MethodInfo = @import("Class/MethodInfo.zig"); +pub const AttributeInfo = @import("Class/AttributeInfo.zig").AttributeInfo; +pub const ConstantPool = @import("Class/ConstantPool.zig"); + pub const ClassAccessFlags = EnumFlags(enum(u16) { public = 0x0001, final = 0x0010, @@ -198,6 +199,10 @@ pub fn jsonStringify(self: *const Self, jws: *std.json.Stringify) !void { try jws.endObject(); } +pub fn acceptFormatter(self: *const Self, formatter: *Formatter) Formatter.Error!void { + try formatter.printField("magic", "0x{X}", .{ self.magic }); +} + pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void { const depth = 2; var indent: u8 = 0; diff --git a/src/Formatter.zig b/src/Formatter.zig new file mode 100644 index 0000000..a38a5eb --- /dev/null +++ b/src/Formatter.zig @@ -0,0 +1,57 @@ +const std = @import("std"); + +pub const Error = error {}; + +vtable: *const VTable, +w: *std.Io.Writer, + +const Self = @This(); + +pub const VTable = struct { + printField: *const fn ( + ptr: *Self, + comptime field: []const u8, + comptime fmt: []const u8, + args: anytype, + ) Error!void, +}; + +pub fn printField( + self: *const Self, + comptime field: []const u8, + value: anytype, +) Error!void { + self.vtable.field(self, field); + self.vtable.value(self, value); +} + +pub const IndentedFormatter = struct { + indent: u8 = 0, + depth: usize = 0, + + interface: Self, + + pub fn init(w: *std.Io.Writer) IndentedFormatter { + return .{ + .interface = .{ + .vtable = &.{ + .printField = IndentedFormatter.printField, + }, + .w = w, + }, + }; + } + + fn printField( + f: *Self, + comptime field: []const u8, + comptime fmt: []const u8, + args: anytype, + ) Error!void { + const self: *IndentedFormatter = @alignCast(@fieldParentPtr("interface", f)); + + _ = try self.interface.w.splatByteAll(' ', self.indent * self.depth); + try self.interface.w.print(field ++ ": " ++ fmt ++ "\n", args); + } +}; + diff --git a/src/main.zig b/src/main.zig index 8c4831e..051ee6d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2,6 +2,8 @@ const std = @import("std"); const Class = @import("Class.zig"); +const Formatter = @import("Formatter.zig"); + pub fn main(init: std.process.Init) !void { const io = init.io; const allocator = init.gpa; @@ -52,7 +54,9 @@ pub fn main(init: std.process.Init) !void { }; defer class.deinit(); - try stdout.print("{f}", .{ class }); + var indented_formatter: Formatter.IndentedFormatter = .init(stdout); + const formatter = &indented_formatter.interface; + try class.acceptFormatter(formatter); try stdout.flush(); }