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); } };