Skip to content

Commit

Permalink
fix master build
Browse files Browse the repository at this point in the history
  • Loading branch information
jiacai2050 committed Sep 23, 2024
1 parent c9ebba7 commit d48eba8
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 31 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
zig-version: [0.13.0]
zig-version: [0.13.0, master]
steps:
- uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -54,7 +54,7 @@ jobs:
targets: [x86_64-windows, x86_64-linux, x86_64-macos, aarch64-macos]
steps:
- uses: actions/checkout@v4
- uses: goto-bus-stop/setup-zig@v2
- uses: mlugg/setup-zig@v1
with:
version: 0.13.0
- name: Build
Expand Down
68 changes: 39 additions & 29 deletions src/mod/simargs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const std = @import("std");
const testing = std.testing;
const is_test = @import("builtin").is_test;
const is_latest_zig = @import("builtin").zig_version.minor > 13;

const ParseError = error{
NoProgram,
Expand Down Expand Up @@ -41,7 +42,7 @@ const OptionField = struct {

fn getOptionLength(comptime T: type) usize {
const option_type_info = @typeInfo(T);
if (option_type_info != .Struct) {
if (!isStruct(option_type_info)) {
@compileError("option should be defined using struct, found " ++ @typeName(T));
}
inline for (std.meta.fields(T)) |fld| {
Expand All @@ -55,12 +56,12 @@ fn getOptionLength(comptime T: type) usize {

fn buildOptionFields(comptime T: type) [getOptionLength(T)]OptionField {
const option_type_info = @typeInfo(T);
if (option_type_info != .Struct) {
if (!isStruct(option_type_info)) {
@compileError("option should be defined using struct, found " ++ @typeName(T));
}

var opt_fields: [getOptionLength(T)]OptionField = undefined;
inline for (option_type_info.Struct.fields, 0..) |fld, idx| {
inline for (std.meta.fields(T), 0..) |fld, idx| {
const long_name = fld.name;
if (std.mem.eql(u8, fld.name, COMMAND_FIELD_NAME)) {
continue;
Expand All @@ -77,7 +78,7 @@ fn buildOptionFields(comptime T: type) [getOptionLength(T)]OptionField {
// parse short names
if (@hasDecl(T, "__shorts__")) {
const shorts_type = @TypeOf(T.__shorts__);
if (@typeInfo(shorts_type) != .Struct) {
if (!isStruct(@typeInfo(shorts_type))) {
@compileError("__shorts__ should be defined using struct, found " ++ @typeName(@typeInfo(shorts_type)));
}

Expand All @@ -86,7 +87,7 @@ fn buildOptionFields(comptime T: type) [getOptionLength(T)]OptionField {
inline for (&opt_fields) |*opt_fld| {
if (std.mem.eql(u8, opt_fld.long_name, long_name)) {
const short_name = @field(T.__shorts__, long_name);
if (@typeInfo(@TypeOf(short_name)) != .EnumLiteral) {
if (@typeInfo(@TypeOf(short_name)) != if (is_latest_zig) .enum_literal else .EnumLiteral) {
@compileError("short option value must be literal enum, found " ++ @typeName(@typeInfo(@TypeOf(short_name))));
}
opt_fld.short_name = @tagName(short_name)[0];
Expand All @@ -102,7 +103,7 @@ fn buildOptionFields(comptime T: type) [getOptionLength(T)]OptionField {
// parse messages
if (@hasDecl(T, "__messages__")) {
const messages_type = @TypeOf(T.__messages__);
if (@typeInfo(messages_type) != .Struct) {
if (!isStruct(@typeInfo(messages_type))) {
@compileError("__messages__ should be defined using struct, found " ++ @typeName(@typeInfo(messages_type)));
}

Expand Down Expand Up @@ -148,7 +149,7 @@ test "build option fields" {

fn NonOptionType(comptime opt_type: type) type {
return switch (@typeInfo(opt_type)) {
.Optional => |o| NonOptionType(o.child),
if (is_latest_zig) .optional else .Optional => |o| NonOptionType(o.child),
else => opt_type,
};
}
Expand All @@ -175,7 +176,7 @@ const MessageHelper = struct {

fn printDefault(comptime f: std.builtin.Type.StructField, writer: anytype) !void {
if (f.default_value == null) {
if (@typeInfo(f.type) != .Optional) {
if (@typeInfo(f.type) != if (is_latest_zig) .optional else .Optional) {
try writer.writeAll("(required)");
}
return;
Expand All @@ -184,24 +185,24 @@ const MessageHelper = struct {
// Don't print default for false (?)bool
const default = @as(*align(1) const f.type, @ptrCast(f.default_value.?)).*;
switch (@typeInfo(f.type)) {
.Bool => if (!default) return,
.Optional => |opt| if (@typeInfo(opt.child) == .Bool)
if (is_latest_zig) .bool else .Bool => if (!default) return,
if (is_latest_zig) .optional else .Optional => |opt| if (@typeInfo(opt.child) == if (is_latest_zig) .bool else .Bool)
if (!(default orelse false)) return,
else => {},
}

const format = "(default: " ++ switch (f.type) {
[]const u8 => "{s}",
?[]const u8 => "{?s}",
else => if (@typeInfo(NonOptionType(f.type)) == .Enum)
else => if (@typeInfo(NonOptionType(f.type)) == if (is_latest_zig) .@"enum" else .Enum)
"{s}"
else
"{any}",
} ++ ")";

try std.fmt.format(writer, format, .{switch (@typeInfo(f.type)) {
.Enum => @tagName(default),
.Optional => |opt| if (@typeInfo(opt.child) == .Enum)
if (is_latest_zig) .@"enum" else .Enum => @tagName(default),
if (is_latest_zig) .optional else .Optional => |opt| if (@typeInfo(opt.child) == if (is_latest_zig) .@"enum" else .Enum)
@tagName(default.?)
else
default,
Expand Down Expand Up @@ -308,7 +309,7 @@ const MessageHelper = struct {
inline for (std.meta.fields(T)) |f| {
if (std.mem.eql(u8, f.name, opt_fld.long_name)) {
const real_type = NonOptionType(f.type);
if (@typeInfo(real_type) == .Enum) {
if (@typeInfo(real_type) == if (is_latest_zig) .@"enum" else .Enum) {
const enum_opts = try std.mem.join(aa, "|", std.meta.fieldNames(real_type));
try writer.writeAll(" (valid: ");
try writer.writeAll(enum_opts);
Expand Down Expand Up @@ -385,18 +386,18 @@ const OptionType = enum(u32) {

fn convert(comptime T: type, comptime is_optional: bool) OptionType {
const base_type: Self = switch (@typeInfo(T)) {
.Int => .RequiredInt,
.Bool => .RequiredBool,
.Float => .RequiredFloat,
.Optional => |opt_info| return Self.convert(opt_info.child, true),
.Pointer => |ptr_info|
if (is_latest_zig) .int else .Int => .RequiredInt,
if (is_latest_zig) .bool else .Bool => .RequiredBool,
if (is_latest_zig) .float else .Float => .RequiredFloat,
if (is_latest_zig) .optional else .Optional => |opt_info| return Self.convert(opt_info.child, true),
if (is_latest_zig) .pointer else .Pointer => |ptr_info|
// only support []const u8
if (ptr_info.size == .Slice and ptr_info.child == u8 and ptr_info.is_const)
.RequiredString
else {
@compileError("not supported option type:" ++ @typeName(T));
},
.Enum => .RequiredEnum,
if (is_latest_zig) .@"enum" else .Enum => .RequiredEnum,
else => {
@compileError("not supported option type:" ++ @typeName(T));
},
Expand Down Expand Up @@ -443,14 +444,14 @@ const MessageWrapper = struct {

fn subCommandsHelpMsg(comptime T: type, comptime len: usize) ?[len]MessageWrapper {
const union_type_info = @typeInfo(T);
if (union_type_info != .Union) {
if (union_type_info != if (is_latest_zig) .@"union" else .Union) {
@compileError("sub commands should be defined using Union(enum), found " ++ @typeName(T));
}

if (@hasDecl(T, "__messages__")) {
const messages_type = @TypeOf(T.__messages__);
if (@typeInfo(messages_type) != .Struct) {
@compileError("__messages__ should be defined using struct, found " ++ @typeName(@typeInfo(messages_type)));
if (comptime !isStruct(@typeInfo(messages_type))) {
@compileError("__messages__ should be defined using struct");
}

var fields: [std.meta.fields(messages_type).len]MessageWrapper = undefined;
Expand All @@ -476,13 +477,13 @@ fn subCommandsHelpMsg(comptime T: type, comptime len: usize) ?[len]MessageWrappe

fn SubCommandsType(comptime T: type) type {
const union_type_info = @typeInfo(T);
if (union_type_info != .Union) {
if (union_type_info != if (is_latest_zig) .@"union" else .Union) {
@compileError("sub commands should be defined using Union(enum), found " ++ @typeName(T));
}

var fields: [std.meta.fields(T).len]std.builtin.Type.StructField = undefined;
inline for (union_type_info.Union.fields, 0..) |fld, idx| {
comptime if (@typeInfo(fld.type) != .Struct) {
inline for (std.meta.fields(T), 0..) |fld, idx| {
comptime if (!isStruct(@typeInfo(fld.type))) {
@compileError("sub command should be defined using struct, found " ++ @typeName(@typeInfo(fld.type)));
};
const FieldType = CommandParser(fld.type);
Expand All @@ -495,7 +496,12 @@ fn SubCommandsType(comptime T: type) type {
.alignment = @alignOf(FieldType),
};
}
return @Type(.{ .Struct = .{
return if (is_latest_zig) @Type(.{ .@"struct" = .{
.layout = .auto,
.fields = &fields,
.decls = &.{},
.is_tuple = false,
} }) else @Type(.{ .Struct = .{
.layout = .auto,
.fields = &fields,
.decls = &.{},
Expand Down Expand Up @@ -748,8 +754,8 @@ fn OptionParser(

fn getSignedness(comptime opt_type: type) std.builtin.Signedness {
return switch (@typeInfo(opt_type)) {
.Int => |i| i.signedness,
.Optional => |o| Self.getSignedness(o.child),
if (is_latest_zig) .int else .Int => |i| i.signedness,
if (is_latest_zig) .optional else .Optional => |o| Self.getSignedness(o.child),
else => @compileError("not int type, have no signedness"),
};
}
Expand Down Expand Up @@ -1140,3 +1146,7 @@ test "parse/sub commands" {
\\
, help_msg.items);
}

fn isStruct(info: std.builtin.Type) bool {
return if (is_latest_zig) info == .@"struct" else info == .Struct;
}

0 comments on commit d48eba8

Please sign in to comment.