Skip to content

Commit

Permalink
checkFields: allow passing strings into optional strings
Browse files Browse the repository at this point in the history
  • Loading branch information
cztomsik committed Mar 27, 2024
1 parent c8bd5e3 commit 6ef0c35
Showing 1 changed file with 19 additions and 16 deletions.
35 changes: 19 additions & 16 deletions src/dsl.zig
Original file line number Diff line number Diff line change
Expand Up @@ -326,25 +326,10 @@ fn checkFields(comptime T: type, comptime D: type) void {
outer: for (@typeInfo(D).Struct.fields) |f| {
for (@typeInfo(T).Struct.fields) |f2| {
if (std.mem.eql(u8, f.name, f2.name)) {
if (f.type == f2.type) {
if (isAssignableTo(f.type, f2.type)) {
continue :outer;
}

if (isString(f.type) and isString(f2.type)) {
continue :outer;
}

switch (@typeInfo(f.type)) {
.ComptimeInt => if (@typeInfo(f2.type) == .Int) continue :outer,
.ComptimeFloat => if (@typeInfo(f2.type) == .Float) continue :outer,
else => {},
}

switch (@typeInfo(f2.type)) {
.Optional => |opt| if (f.type == opt.child) continue :outer,
else => {},
}

@compileError(
"Type mismatch for field " ++ f.name ++
" found:" ++ @typeName(f.type) ++
Expand All @@ -358,6 +343,24 @@ fn checkFields(comptime T: type, comptime D: type) void {
}
}

fn isAssignableTo(comptime A: type, B: type) bool {
if (A == B) return true;
if (isString(A) and isString(B)) return true;

switch (@typeInfo(A)) {
.ComptimeInt => if (@typeInfo(B) == .Int) return true,
.ComptimeFloat => if (@typeInfo(B) == .Float) return true,
else => {},
}

switch (@typeInfo(B)) {
.Optional => |opt| if (isAssignableTo(A, opt.child)) return true,
else => {},
}

return false;
}

pub fn isString(comptime T: type) bool {
return switch (@typeInfo(T)) {
.Pointer => |ptr| ptr.child == u8 or switch (@typeInfo(ptr.child)) {
Expand Down

0 comments on commit 6ef0c35

Please sign in to comment.