initial commit
This commit is contained in:
70
src/main.zig
Normal file
70
src/main.zig
Normal file
@@ -0,0 +1,70 @@
|
||||
const std = @import("std");
|
||||
const zlog = @import("zlog");
|
||||
|
||||
const Options = enum {
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
};
|
||||
|
||||
const Struct = struct {
|
||||
a: usize = 42,
|
||||
b: bool = true,
|
||||
c: [5]u16 = .{ 1, 2, 3, 4, 5 },
|
||||
d: []const u8 = "string",
|
||||
e: Options = Options.b,
|
||||
|
||||
// pub fn format(value: Struct, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
// // TODO: make the creation of this function comptime
|
||||
// try writer.writeAll("main.Struct{ ");
|
||||
// try writer.writeAll(".a: usize = ");
|
||||
// try std.fmt.formatIntValue(value.a, fmt, options, writer);
|
||||
// try writer.writeAll(", ");
|
||||
|
||||
// try writer.writeAll(".b: bool = ");
|
||||
// try std.fmt.formatBuf(if (value.b) "true" else "false", options, writer);
|
||||
// try writer.writeAll(", ");
|
||||
|
||||
// try writer.writeAll(".c: [5]u16 = ");
|
||||
// try std.fmt.format(writer, "{any}", .{value.c});
|
||||
// try writer.writeAll(", ");
|
||||
|
||||
// try writer.writeAll(".d: []const u8 = ");
|
||||
// try std.fmt.format(writer, "\"{s}\"", .{value.d});
|
||||
// try writer.writeAll(", ");
|
||||
|
||||
// try writer.writeAll(".e: main.Options = ");
|
||||
// try std.fmt.format(writer, "{any}", .{value.e});
|
||||
|
||||
// try writer.writeAll(" }");
|
||||
// }
|
||||
|
||||
// TODO: can this become comptime entirely? - i.e. create the entire struct through a helper function and provide the created one with the format function already attached?
|
||||
pub fn format(value: Struct, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) anyerror!void {
|
||||
try zlog.generic_format(value, fmt, options, writer);
|
||||
}
|
||||
};
|
||||
|
||||
pub const std_options = zlog.std_options;
|
||||
|
||||
pub fn main() void {
|
||||
// initialize zlog with the scope of `main`
|
||||
const log = std.log.scoped(.main);
|
||||
// NOTE: the scope of `default` will result in no scoping being printed in
|
||||
// the resulting output
|
||||
|
||||
// some variables to log
|
||||
const int_var = 42;
|
||||
const array_var = [_]i32{ 1, 2, 3, 4 };
|
||||
const string_var = "This is a test";
|
||||
const option_var = Options.a;
|
||||
const struct_var: Struct = .{};
|
||||
|
||||
// NOTE: Depending on the optimization target some of these log messages
|
||||
// will not show, which is inline with the behavior of `std.log`.
|
||||
log.debug("Debug message {any}", .{int_var});
|
||||
log.info("Info message {any}", .{array_var});
|
||||
log.info("Info message \"{s}\"", .{string_var});
|
||||
log.warn("Warning message {any}", .{option_var});
|
||||
log.err("Error message {any}", .{struct_var});
|
||||
}
|
||||
88
src/zlog.zig
Normal file
88
src/zlog.zig
Normal file
@@ -0,0 +1,88 @@
|
||||
const std = @import("std");
|
||||
|
||||
const max_depth = 5;
|
||||
|
||||
// pub fn format(value: ?, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void
|
||||
// TODO: provide comptime helper function to add format function for user types:
|
||||
// - pretty printing
|
||||
// - compact printing
|
||||
// - show types of struct members
|
||||
// Maybe the corresponding configurations for the `format` function could also
|
||||
// be effected by build time configurations
|
||||
|
||||
pub const std_options: std.Options = .{
|
||||
.logFn = logFn,
|
||||
};
|
||||
|
||||
// zlog defaultLog function replacement, which adjusts the surrounding contents of every std.log message.
|
||||
fn logFn(
|
||||
comptime message_level: std.log.Level,
|
||||
comptime scope: @Type(.EnumLiteral),
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) void {
|
||||
// TODO: provide build time configuration to allow tweaking corresponding output
|
||||
// - add timestamp to all log messages
|
||||
// - change output file for writing messages to (default `stderr`)
|
||||
|
||||
// TODO: improve formatting output, such that the resulting log has a good feel
|
||||
// - should there be indenting?
|
||||
// - should there be spacing?
|
||||
// - should the messages be aligned (left, center, right)?
|
||||
const level_txt = comptime message_level.asText();
|
||||
const prefix2 = if (scope == .default) ":\t" else "(" ++ @tagName(scope) ++ "):\t";
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
var bw = std.io.bufferedWriter(stderr);
|
||||
const writer = bw.writer();
|
||||
|
||||
std.debug.lockStdErr();
|
||||
defer std.debug.unlockStdErr();
|
||||
nosuspend {
|
||||
writer.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;
|
||||
bw.flush() catch return;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generic_format(object: anytype, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
_ = fmt;
|
||||
_ = options;
|
||||
const Object = @TypeOf(object);
|
||||
const object_info = @typeInfo(Object);
|
||||
switch (object_info) {
|
||||
.Struct => |s| {
|
||||
try writer.writeAll(@typeName(Object));
|
||||
try writer.writeAll(" = {\n");
|
||||
inline for (s.fields) |field| {
|
||||
try writer.writeAll("\t .");
|
||||
try writer.writeAll(field.name);
|
||||
try writer.writeAll(" = ");
|
||||
// TODO check corresponding type and try to adapt fmt accordingly!
|
||||
try std.fmt.format(writer, "{any}", .{@field(object, field.name)});
|
||||
try writer.writeAll(",\n");
|
||||
}
|
||||
try writer.writeAll("}");
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enhance_format(comptime object: type) type {
|
||||
// TODO: append a function to the type if it is a user defined type
|
||||
|
||||
// NOTE: this has the clear disadvantage that the type is not the same anymore! (but maybe this is still fine)
|
||||
const object_info = @typeInfo(object);
|
||||
switch (object_info) {
|
||||
.Struct => |s| {
|
||||
return @Type(.{
|
||||
.Struct = .{
|
||||
.layout = .auto,
|
||||
.fields = s.fields,
|
||||
.decls = s.decls,
|
||||
.is_tuple = false,
|
||||
},
|
||||
});
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
return object;
|
||||
}
|
||||
Reference in New Issue
Block a user