config: union type formatters

This commit is contained in:
Mitchell Hashimoto
2024-01-20 15:35:16 -08:00
parent 95a67e5f06
commit daf297cee2
3 changed files with 113 additions and 2 deletions

View File

@ -3065,6 +3065,20 @@ pub const FontStyle = union(enum) {
};
}
/// Used by Formatter
pub fn formatEntry(self: Self, formatter: anytype) !void {
switch (self) {
.default, .false => try formatter.formatEntry(
[]const u8,
@tagName(self),
),
.name => |name| {
try formatter.formatEntry([:0]const u8, name);
},
}
}
test "parseCLI" {
const testing = std.testing;
var arena = ArenaAllocator.init(testing.allocator);
@ -3081,6 +3095,51 @@ pub const FontStyle = union(enum) {
try p.parseCLI(alloc, "bold");
try testing.expectEqualStrings("bold", p.name);
}
test "formatConfig default" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
defer arena.deinit();
const alloc = arena.allocator();
var p: Self = .{ .default = {} };
try p.parseCLI(alloc, "default");
try p.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = default\n", buf.items);
}
test "formatConfig false" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
defer arena.deinit();
const alloc = arena.allocator();
var p: Self = .{ .default = {} };
try p.parseCLI(alloc, "false");
try p.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = false\n", buf.items);
}
test "formatConfig named" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
defer arena.deinit();
const alloc = arena.allocator();
var p: Self = .{ .default = {} };
try p.parseCLI(alloc, "bold");
try p.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = bold\n", buf.items);
}
};
/// See "link" for documentation.

View File

@ -113,8 +113,10 @@ pub fn formatEntry(
else => {},
},
// TODO
.Union => return,
.Union => if (@hasDecl(T, "formatEntry")) {
try value.formatEntry(entryFormatter(name, writer));
return;
},
else => {},
}

View File

@ -119,6 +119,34 @@ pub const Modifier = union(enum) {
return try parse(input orelse return error.ValueRequired);
}
/// Used by config formatter
pub fn formatEntry(self: Modifier, formatter: anytype) !void {
var buf: [1024]u8 = undefined;
switch (self) {
.percent => |v| {
try formatter.formatEntry(
[]const u8,
std.fmt.bufPrint(
&buf,
"{d}%",
.{(v - 1) * 100},
) catch return error.OutOfMemory,
);
},
.absolute => |v| {
try formatter.formatEntry(
[]const u8,
std.fmt.bufPrint(
&buf,
"{d}",
.{v},
) catch return error.OutOfMemory,
);
},
}
}
/// Apply a modifier to a numeric value.
pub fn apply(self: Modifier, v: u32) u32 {
return switch (self) {
@ -140,6 +168,28 @@ pub const Modifier = union(enum) {
},
};
}
test "formatConfig percent" {
const configpkg = @import("../../config.zig");
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
defer buf.deinit();
const p = try parseCLI("24%");
try p.formatEntry(configpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = 24%\n", buf.items);
}
test "formatConfig absolute" {
const configpkg = @import("../../config.zig");
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
defer buf.deinit();
const p = try parseCLI("-30");
try p.formatEntry(configpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = -30\n", buf.items);
}
};
/// Key is an enum of all the available metrics keys.