@@ -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 ) {
0 commit comments