feature. See also
. The project being documented here (as the example) is the Zig library itself.
Build.addUserInputOptionFromArg
fn addUserInputOptionFromArg(
arena: Allocator,
map: *UserInputOptionsMap,
field_name: [:0]const u8,
comptime T: type,
maybe_value: ?T,
) void
File
Code
fn addUserInputOptionFromArg(
arena: Allocator,
map: *UserInputOptionsMap,
field_name: [:0]const u8,
comptime T: type,
maybe_value: ?T,
) void {
switch (T) {
Target.Query => return if (maybe_value) |v| {
map.put(field_name, .{
.name = field_name,
.value = .{ .scalar = v.zigTriple(arena) catch @panic("OOM") },
.used = false,
}) catch @panic("OOM");
map.put("cpu", .{
.name = "cpu",
.value = .{ .scalar = v.serializeCpuAlloc(arena) catch @panic("OOM") },
.used = false,
}) catch @panic("OOM");
},
ResolvedTarget => return if (maybe_value) |v| {
map.put(field_name, .{
.name = field_name,
.value = .{ .scalar = v.query.zigTriple(arena) catch @panic("OOM") },
.used = false,
}) catch @panic("OOM");
map.put("cpu", .{
.name = "cpu",
.value = .{ .scalar = v.query.serializeCpuAlloc(arena) catch @panic("OOM") },
.used = false,
}) catch @panic("OOM");
},
std.zig.BuildId => return if (maybe_value) |v| {
map.put(field_name, .{
.name = field_name,
.value = .{ .scalar = std.fmt.allocPrint(arena, "{f}", .{v}) catch @panic("OOM") },
.used = false,
}) catch @panic("OOM");
},
LazyPath => return if (maybe_value) |v| {
map.put(field_name, .{
.name = field_name,
.value = .{ .lazy_path = v.dupeInner(arena) },
.used = false,
}) catch @panic("OOM");
},
[]const LazyPath => return if (maybe_value) |v| {
var list = std.array_list.Managed(LazyPath).initCapacity(arena, v.len) catch @panic("OOM");
for (v) |lp| list.appendAssumeCapacity(lp.dupeInner(arena));
map.put(field_name, .{
.name = field_name,
.value = .{ .lazy_path_list = list },
.used = false,
}) catch @panic("OOM");
},
[]const u8 => return if (maybe_value) |v| {
map.put(field_name, .{
.name = field_name,
.value = .{ .scalar = arena.dupe(u8, v) catch @panic("OOM") },
.used = false,
}) catch @panic("OOM");
},
[]const []const u8 => return if (maybe_value) |v| {
var list = std.array_list.Managed([]const u8).initCapacity(arena, v.len) catch @panic("OOM");
for (v) |s| list.appendAssumeCapacity(arena.dupe(u8, s) catch @panic("OOM"));
map.put(field_name, .{
.name = field_name,
.value = .{ .list = list },
.used = false,
}) catch @panic("OOM");
},
else => switch (@typeInfo(T)) {
.bool => return if (maybe_value) |v| {
map.put(field_name, .{
.name = field_name,
.value = .{ .scalar = if (v) "true" else "false" },
.used = false,
}) catch @panic("OOM");
},
.@"enum", .enum_literal => return if (maybe_value) |v| {
map.put(field_name, .{
.name = field_name,
.value = .{ .scalar = @tagName(v) },
.used = false,
}) catch @panic("OOM");
},
.comptime_int, .int => return if (maybe_value) |v| {
map.put(field_name, .{
.name = field_name,
.value = .{ .scalar = std.fmt.allocPrint(arena, "{d}", .{v}) catch @panic("OOM") },
.used = false,
}) catch @panic("OOM");
},
.comptime_float, .float => return if (maybe_value) |v| {
map.put(field_name, .{
.name = field_name,
.value = .{ .scalar = std.fmt.allocPrint(arena, "{x}", .{v}) catch @panic("OOM") },
.used = false,
}) catch @panic("OOM");
},
.pointer => |ptr_info| switch (ptr_info.size) {
.one => switch (@typeInfo(ptr_info.child)) {
.array => |array_info| {
addUserInputOptionFromArg(
arena,
map,
field_name,
@Pointer(.slice, .{ .@"const" = true }, array_info.child, null),
maybe_value orelse null,
);
return;
},
else => {},
},
.slice => switch (@typeInfo(ptr_info.child)) {
.@"enum" => return if (maybe_value) |v| {
var list = std.array_list.Managed([]const u8).initCapacity(arena, v.len) catch @panic("OOM");
for (v) |tag| list.appendAssumeCapacity(@tagName(tag));
map.put(field_name, .{
.name = field_name,
.value = .{ .list = list },
.used = false,
}) catch @panic("OOM");
},
else => {
addUserInputOptionFromArg(
arena,
map,
field_name,
@Pointer(ptr_info.size, .{ .@"const" = true }, ptr_info.child, null),
maybe_value orelse null,
);
return;
},
},
else => {},
},
.null => unreachable,
.optional => |info| switch (@typeInfo(info.child)) {
.optional => {},
else => {
addUserInputOptionFromArg(
arena,
map,
field_name,
info.child,
maybe_value orelse null,
);
return;
},
},
else => {},
},
}
@compileError("option '" ++ field_name ++ "' has unsupported type: " ++ @typeName(T));
}