config: support parsing enums

This commit is contained in:
Mitchell Hashimoto
2023-07-06 17:56:19 -07:00
parent 80e2cd4e78
commit 18e43ddb3f

View File

@ -91,11 +91,11 @@ fn parseIntoField(
.Optional => |opt| opt.child,
else => field.type,
};
const fieldInfo = @typeInfo(Field);
// If we are a struct and have parseCLI, we call that and use
// that to set the value.
if (fieldInfo == .Struct and @hasDecl(Field, "parseCLI")) {
switch (@typeInfo(Field)) {
.Struct => if (@hasDecl(Field, "parseCLI")) {
const fnInfo = @typeInfo(@TypeOf(Field.parseCLI)).Fn;
switch (fnInfo.params.len) {
// 1 arg = (input) => output
@ -111,6 +111,17 @@ fn parseIntoField(
}
return;
},
.Enum => {
@field(dst, field.name) = std.meta.stringToEnum(
Field,
value orelse return error.ValueRequired,
) orelse return error.InvalidValue;
return;
},
else => {},
}
// No parseCLI, magic the value based on the type
@ -317,6 +328,21 @@ test "parseIntoField: floats" {
try testing.expectEqual(@as(f64, 1.0), data.f64);
}
test "parseIntoField: enums" {
const testing = std.testing;
var arena = ArenaAllocator.init(testing.allocator);
defer arena.deinit();
const alloc = arena.allocator();
const Enum = enum { one, two, three };
var data: struct {
v: Enum,
} = undefined;
try parseIntoField(@TypeOf(data), alloc, &data, "v", "two");
try testing.expectEqual(Enum.two, data.v);
}
test "parseIntoField: optional field" {
const testing = std.testing;
var arena = ArenaAllocator.init(testing.allocator);