diff --git a/src/gtl.zig b/src/gtl.zig index 6058a0c..9a06967 100644 --- a/src/gtl.zig +++ b/src/gtl.zig @@ -121,11 +121,64 @@ test "SlotMap" { } { - log.warn("...", .{}); - log.err("...", .{}); - log.info("...", .{}); - log.debug("...", .{}); - log.trace("...", .{}); + // --- LOG --- + log.warn("...", .{}, @src()); + log.err("...", .{}, @src()); + log.info("...", .{}, @src()); + log.debug("...", .{}, @src()); + log.trace("...", .{}, @src()); + + // --- PRINT --- + if (log.print(.debug, "DEVICE INFO", ansi.bold ++ ansi.red)) |a| { + defer a.end(); + + // --- VALUES --- + a.write("device -> {s}", .{"GTX"}); + a.write("vendor -> {s}", .{"Nvidia"}); + + // --- SECTION --- + if (a.section(.err, "MEMORY", ansi.green)) |b| { + defer b.end(); + + b.write("VRAM -> {}GB", .{24}); + } + } + + log.set(.{ .style = .rounded }); + + // --- PRINT --- + if (log.print(.debug, "DEVICE INFO", ansi.bold ++ ansi.red)) |a| { + defer a.end(); + + // --- VALUES --- + a.write("device -> {s}", .{"GTX"}); + a.write("vendor -> {s}", .{"Nvidia"}); + + // --- SECTION --- + if (a.section(.err, "MEMORY", ansi.green)) |b| { + defer b.end(); + + b.write("VRAM -> {}GB", .{24}); + } + } + + log.set(.{ .style = .pipe }); + + // --- PRINT --- + if (log.print(.debug, "DEVICE INFO", ansi.bold ++ ansi.red)) |a| { + defer a.end(); + + // --- VALUES --- + a.write("device -> {s}", .{"GTX"}); + a.write("vendor -> {s}", .{"Nvidia"}); + + // --- SECTION --- + if (a.section(.err, "MEMORY", ansi.green)) |b| { + defer b.end(); + + b.write("VRAM -> {}GB", .{24}); + } + } } var ring: RingBuffer([]const u8, 3) = .{}; diff --git a/src/log.zig b/src/log.zig index 1ba3d68..a200cd2 100644 --- a/src/log.zig +++ b/src/log.zig @@ -34,11 +34,27 @@ pub const Level = enum(u8) { } }; +/// ---------------------------------------------------- +/// ---------------------------------------------------- +const BoxChars = struct { + horizontal: []const u8, + vertical: []const u8, + + top_left: []const u8, + bottom_left: []const u8, +}; + /// ---------------------------------------------------- /// ---------------------------------------------------- pub const Config = struct { level: Level = .debug, source_loc: bool = true, + style: union(enum) { + default, + rounded, + pipe, + custom: BoxChars, + } = .default, }; // --- CONFIG --- @@ -52,42 +68,185 @@ pub fn set(c: Config) void { /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn debug(comptime fmt: []const u8, args: anytype) void { - log(.debug, @src(), fmt, args); +pub fn debug(comptime fmt: []const u8, args: anytype, src: std.builtin.SourceLocation) void { + log(.debug, src, fmt, args); } /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn trace(comptime fmt: []const u8, args: anytype) void { - log(.trace, @src(), fmt, args); +pub fn trace(comptime fmt: []const u8, args: anytype, src: std.builtin.SourceLocation) void { + log(.trace, src, fmt, args); } /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn info(comptime fmt: []const u8, args: anytype) void { - log(.info, @src(), fmt, args); +pub fn info(comptime fmt: []const u8, args: anytype, src: std.builtin.SourceLocation) void { + log(.info, src, fmt, args); } /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn warn(comptime fmt: []const u8, args: anytype) void { - log(.warn, @src(), fmt, args); +pub fn warn(comptime fmt: []const u8, args: anytype, src: std.builtin.SourceLocation) void { + log(.warn, src, fmt, args); } /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn err(comptime fmt: []const u8, args: anytype) void { - log(.err, @src(), fmt, args); +pub fn err(comptime fmt: []const u8, args: anytype, src: std.builtin.SourceLocation) void { + log(.err, src, fmt, args); } /// ---------------------------------------------------- /// Uses **@breakpoint()** /// ---------------------------------------------------- -pub fn fatal(comptime fmt: []const u8, args: anytype) void { - log(.fatal, @src(), fmt, args); +pub fn fatal(comptime fmt: []const u8, args: anytype, src: std.builtin.SourceLocation) void { + log(.fatal, src, fmt, args); if (@import("builtin").mode == .Debug) @breakpoint(); } +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub const Print = struct { + + // + // FIELDS + // + + color: []const u8, + depth: usize = 0, + colors: [16][]const u8 = std.mem.zeroes([16][]const u8), + + /// ---------------------------------------------------- + /// ---------------------------------------------------- + pub fn write(self: Print, comptime fmt: []const u8, args: anytype) void { + const box = boxChars(); + printPrefix(self.depth, self.colors[0..self.depth]); + std.debug.print("{s}{s}{s}", .{ self.color, box.vertical, ansi.reset }); + std.debug.print(" " ++ fmt ++ "\n", args); + } + + /// ---------------------------------------------------- + /// ---------------------------------------------------- + pub fn separator(self: Print) void { + const box = boxChars(); + std.debug.print("{s}{s}{s}\n", .{ self.color, box.vertical, ansi.reset }); + } + + /// ---------------------------------------------------- + /// ---------------------------------------------------- + pub fn prefix(self: Print) void { + const box = boxChars(); + std.debug.print("{s}{s}{s} ", .{ self.color, box.vertical, ansi.reset }); + } + + /// ---------------------------------------------------- + /// ---------------------------------------------------- + pub fn end(self: Print) void { + const box = boxChars(); + printPrefix(self.depth, self.colors[0..self.depth]); + std.debug.print("{s}{s}{s}{s}\n", .{ self.color, box.bottom_left, box.horizontal, ansi.reset }); + } + + /// ---------------------------------------------------- + /// ---------------------------------------------------- + pub fn section( + self: Print, + level: Level, + name: []const u8, + color: []const u8, + ) ?Print { + if (@intFromEnum(level) < @intFromEnum(config.level)) + return null; + + const box = boxChars(); + + // Print parent's prefix. + printPrefix(self.depth, self.colors[0..self.depth]); + std.debug.print("{s}{s}{s} ", .{ + self.color, + box.vertical, + ansi.reset, + }); + + std.debug.print( + "{s}{s}{s}{s} {s}\n", + .{ + color, + box.top_left, + box.horizontal, + ansi.reset, + name, + }, + ); + + var child: Print = .{ .color = color, .depth = self.depth + 1 }; + child.colors = self.colors; + child.colors[self.depth] = self.color; + return child; + } + + /// ---------------------------------------------------- + /// ---------------------------------------------------- + fn printPrefix(depth: usize, colors: []const []const u8) void { + const box = boxChars(); + var i: usize = 0; + while (i < depth) : (i += 1) { + std.debug.print("{s}{s}{s} ", .{ + colors[i], + box.vertical, + ansi.reset, + }); + } + } +}; + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn print( + level: Level, + name: []const u8, + color: []const u8, +) ?Print { + // --- CHECK LOG LVL --- + if (@intFromEnum(level) < @intFromEnum(config.level)) return null; + + // --- RESULT --- + const box = boxChars(); + std.debug.print("{s}{s}{s}{s} {s}\n", .{ color, box.top_left, box.horizontal, ansi.reset, name }); + return .{ .color = color }; +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn boxChars() BoxChars { + return switch (config.style) { + .default => .{ + .horizontal = "━", + .vertical = "┃", + .top_left = "┏", + .bottom_left = "┗", + }, + .rounded => .{ + .horizontal = "─", + .vertical = "│", + .top_left = "╭", + .bottom_left = "╰", + }, + .pipe => .{ + .horizontal = "═", + .vertical = "║", + .top_left = "╔", + .bottom_left = "╚", + }, + .custom => |style| .{ + .horizontal = style.horizontal, + .vertical = style.vertical, + .top_left = style.top_left, + .bottom_left = style.bottom_left, + }, + }; +} + /// ---------------------------------------------------- /// ---------------------------------------------------- fn log( @@ -107,9 +266,7 @@ fn log( // --- WRITE --- const w = &stderr.file_writer.interface; w.writeAll(level.color()) catch return; - w.print("[" ++ ansi.bold ++ "{s}" ++ ansi.reset, .{level.label()}) catch return; - w.writeAll(level.color()) catch return; - w.writeAll("]" ++ ansi.reset ++ " ") catch return; + w.print(ansi.bold ++ "[{s:<5}]" ++ ansi.reset ++ " ", .{level.label()}) catch return; // --- CHECK LOCATION --- if (config.source_loc) {