| ... | ... | @@ -408,104 +408,127 @@ fn createChildOnly( |
| 408 | 408 | return child; |
| 409 | 409 | } |
| 410 | 410 | |
| 411 | | fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOptionsMap { |
| 412 | | var user_input_options = UserInputOptionsMap.init(allocator); |
| 411 | fn userInputOptionsFromArgs(arena: Allocator, args: anytype) UserInputOptionsMap { |
| 412 | var map = UserInputOptionsMap.init(arena); |
| 413 | 413 | inline for (@typeInfo(@TypeOf(args)).@"struct".fields) |field| { |
| 414 | | const v = @field(args, field.name); |
| 415 | | const T = @TypeOf(v); |
| 416 | | switch (T) { |
| 417 | | Target.Query => { |
| 418 | | user_input_options.put(field.name, .{ |
| 419 | | .name = field.name, |
| 420 | | .value = .{ .scalar = v.zigTriple(allocator) catch @panic("OOM") }, |
| 421 | | .used = false, |
| 422 | | }) catch @panic("OOM"); |
| 423 | | user_input_options.put("cpu", .{ |
| 424 | | .name = "cpu", |
| 425 | | .value = .{ .scalar = v.serializeCpuAlloc(allocator) catch @panic("OOM") }, |
| 426 | | .used = false, |
| 427 | | }) catch @panic("OOM"); |
| 428 | | }, |
| 429 | | ResolvedTarget => { |
| 430 | | user_input_options.put(field.name, .{ |
| 431 | | .name = field.name, |
| 432 | | .value = .{ .scalar = v.query.zigTriple(allocator) catch @panic("OOM") }, |
| 433 | | .used = false, |
| 434 | | }) catch @panic("OOM"); |
| 435 | | user_input_options.put("cpu", .{ |
| 436 | | .name = "cpu", |
| 437 | | .value = .{ .scalar = v.query.serializeCpuAlloc(allocator) catch @panic("OOM") }, |
| 438 | | .used = false, |
| 439 | | }) catch @panic("OOM"); |
| 440 | | }, |
| 441 | | LazyPath => { |
| 442 | | user_input_options.put(field.name, .{ |
| 414 | if (field.type == @Type(.null)) continue; |
| 415 | addUserInputOptionFromArg(arena, &map, field, field.type, @field(args, field.name)); |
| 416 | } |
| 417 | return map; |
| 418 | } |
| 419 | |
| 420 | fn addUserInputOptionFromArg( |
| 421 | arena: Allocator, |
| 422 | map: *UserInputOptionsMap, |
| 423 | field: std.builtin.Type.StructField, |
| 424 | comptime T: type, |
| 425 | /// If null, the value won't be added, but `T` will still be type-checked. |
| 426 | maybe_value: ?T, |
| 427 | ) void { |
| 428 | switch (T) { |
| 429 | Target.Query => return if (maybe_value) |v| { |
| 430 | map.put(field.name, .{ |
| 431 | .name = field.name, |
| 432 | .value = .{ .scalar = v.zigTriple(arena) catch @panic("OOM") }, |
| 433 | .used = false, |
| 434 | }) catch @panic("OOM"); |
| 435 | map.put("cpu", .{ |
| 436 | .name = "cpu", |
| 437 | .value = .{ .scalar = v.serializeCpuAlloc(arena) catch @panic("OOM") }, |
| 438 | .used = false, |
| 439 | }) catch @panic("OOM"); |
| 440 | }, |
| 441 | ResolvedTarget => return if (maybe_value) |v| { |
| 442 | map.put(field.name, .{ |
| 443 | .name = field.name, |
| 444 | .value = .{ .scalar = v.query.zigTriple(arena) catch @panic("OOM") }, |
| 445 | .used = false, |
| 446 | }) catch @panic("OOM"); |
| 447 | map.put("cpu", .{ |
| 448 | .name = "cpu", |
| 449 | .value = .{ .scalar = v.query.serializeCpuAlloc(arena) catch @panic("OOM") }, |
| 450 | .used = false, |
| 451 | }) catch @panic("OOM"); |
| 452 | }, |
| 453 | LazyPath => return if (maybe_value) |v| { |
| 454 | map.put(field.name, .{ |
| 455 | .name = field.name, |
| 456 | .value = .{ .lazy_path = v.dupeInner(arena) }, |
| 457 | .used = false, |
| 458 | }) catch @panic("OOM"); |
| 459 | }, |
| 460 | []const LazyPath => return if (maybe_value) |v| { |
| 461 | var list = ArrayList(LazyPath).initCapacity(arena, v.len) catch @panic("OOM"); |
| 462 | for (v) |lp| list.appendAssumeCapacity(lp.dupeInner(arena)); |
| 463 | map.put(field.name, .{ |
| 464 | .name = field.name, |
| 465 | .value = .{ .lazy_path_list = list }, |
| 466 | .used = false, |
| 467 | }) catch @panic("OOM"); |
| 468 | }, |
| 469 | []const u8 => return if (maybe_value) |v| { |
| 470 | map.put(field.name, .{ |
| 471 | .name = field.name, |
| 472 | .value = .{ .scalar = v }, |
| 473 | .used = false, |
| 474 | }) catch @panic("OOM"); |
| 475 | }, |
| 476 | []const []const u8 => return if (maybe_value) |v| { |
| 477 | var list = ArrayList([]const u8).initCapacity(arena, v.len) catch @panic("OOM"); |
| 478 | list.appendSliceAssumeCapacity(v); |
| 479 | map.put(field.name, .{ |
| 480 | .name = field.name, |
| 481 | .value = .{ .list = list }, |
| 482 | .used = false, |
| 483 | }) catch @panic("OOM"); |
| 484 | }, |
| 485 | else => switch (@typeInfo(T)) { |
| 486 | .bool => return if (maybe_value) |v| { |
| 487 | map.put(field.name, .{ |
| 443 | 488 | .name = field.name, |
| 444 | | .value = .{ .lazy_path = v.dupeInner(allocator) }, |
| 489 | .value = .{ .scalar = if (v) "true" else "false" }, |
| 445 | 490 | .used = false, |
| 446 | 491 | }) catch @panic("OOM"); |
| 447 | 492 | }, |
| 448 | | []const LazyPath => { |
| 449 | | var list = ArrayList(LazyPath).initCapacity(allocator, v.len) catch @panic("OOM"); |
| 450 | | for (v) |lp| list.appendAssumeCapacity(lp.dupeInner(allocator)); |
| 451 | | user_input_options.put(field.name, .{ |
| 493 | .@"enum", .enum_literal => return if (maybe_value) |v| { |
| 494 | map.put(field.name, .{ |
| 452 | 495 | .name = field.name, |
| 453 | | .value = .{ .lazy_path_list = list }, |
| 496 | .value = .{ .scalar = @tagName(v) }, |
| 454 | 497 | .used = false, |
| 455 | 498 | }) catch @panic("OOM"); |
| 456 | 499 | }, |
| 457 | | []const u8 => { |
| 458 | | user_input_options.put(field.name, .{ |
| 500 | .comptime_int, .int => return if (maybe_value) |v| { |
| 501 | map.put(field.name, .{ |
| 459 | 502 | .name = field.name, |
| 460 | | .value = .{ .scalar = v }, |
| 503 | .value = .{ .scalar = std.fmt.allocPrint(arena, "{d}", .{v}) catch @panic("OOM") }, |
| 461 | 504 | .used = false, |
| 462 | 505 | }) catch @panic("OOM"); |
| 463 | 506 | }, |
| 464 | | []const []const u8 => { |
| 465 | | var list = ArrayList([]const u8).initCapacity(allocator, v.len) catch @panic("OOM"); |
| 466 | | list.appendSliceAssumeCapacity(v); |
| 467 | | |
| 468 | | user_input_options.put(field.name, .{ |
| 507 | .comptime_float, .float => return if (maybe_value) |v| { |
| 508 | map.put(field.name, .{ |
| 469 | 509 | .name = field.name, |
| 470 | | .value = .{ .list = list }, |
| 510 | .value = .{ .scalar = std.fmt.allocPrint(arena, "{e}", .{v}) catch @panic("OOM") }, |
| 471 | 511 | .used = false, |
| 472 | 512 | }) catch @panic("OOM"); |
| 473 | 513 | }, |
| 474 | | else => switch (@typeInfo(T)) { |
| 475 | | .bool => { |
| 476 | | user_input_options.put(field.name, .{ |
| 477 | | .name = field.name, |
| 478 | | .value = .{ .scalar = if (v) "true" else "false" }, |
| 479 | | .used = false, |
| 480 | | }) catch @panic("OOM"); |
| 481 | | }, |
| 482 | | .@"enum", .enum_literal => { |
| 483 | | user_input_options.put(field.name, .{ |
| 484 | | .name = field.name, |
| 485 | | .value = .{ .scalar = @tagName(v) }, |
| 486 | | .used = false, |
| 487 | | }) catch @panic("OOM"); |
| 488 | | }, |
| 489 | | .comptime_int, .int => { |
| 490 | | user_input_options.put(field.name, .{ |
| 491 | | .name = field.name, |
| 492 | | .value = .{ .scalar = std.fmt.allocPrint(allocator, "{d}", .{v}) catch @panic("OOM") }, |
| 493 | | .used = false, |
| 494 | | }) catch @panic("OOM"); |
| 514 | .null => unreachable, |
| 515 | .optional => |info| switch (@typeInfo(info.child)) { |
| 516 | .optional => {}, |
| 517 | else => { |
| 518 | addUserInputOptionFromArg( |
| 519 | arena, |
| 520 | map, |
| 521 | field, |
| 522 | info.child, |
| 523 | maybe_value orelse null, |
| 524 | ); |
| 525 | return; |
| 495 | 526 | }, |
| 496 | | .comptime_float, .float => { |
| 497 | | user_input_options.put(field.name, .{ |
| 498 | | .name = field.name, |
| 499 | | .value = .{ .scalar = std.fmt.allocPrint(allocator, "{e}", .{v}) catch @panic("OOM") }, |
| 500 | | .used = false, |
| 501 | | }) catch @panic("OOM"); |
| 502 | | }, |
| 503 | | else => @compileError("option '" ++ field.name ++ "' has unsupported type: " ++ @typeName(T)), |
| 504 | 527 | }, |
| 505 | | } |
| 528 | else => {}, |
| 529 | }, |
| 506 | 530 | } |
| 507 | | |
| 508 | | return user_input_options; |
| 531 | @compileError("option '" ++ field.name ++ "' has unsupported type: " ++ @typeName(field.type)); |
| 509 | 532 | } |
| 510 | 533 | |
| 511 | 534 | const OrderedUserValue = union(enum) { |