Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

expectEqualInner

testing.expectEqualInner
fn expectEqualInner(comptime T: type, expected: T, actual: T) !void

File

lib/std/testing.zig:78

Code

fn expectEqualInner(comptime T: type, expected: T, actual: T) !void {
    switch (@typeInfo(@TypeOf(actual))) {
        .noreturn,
        .@"opaque",
        .spirv,
        .frame,
        .@"anyframe",
        => @compileError("value of type " ++ @typeName(@TypeOf(actual)) ++ " encountered"),

        .undefined,
        .null,
        .void,
        => return,

        .type => {
            if (actual != expected) {
                print("expected type {s}, found type {s}\n", .{ @typeName(expected), @typeName(actual) });
                return error.TestExpectedEqual;
            }
        },

        .bool,
        .int,
        .float,
        .comptime_float,
        .comptime_int,
        .enum_literal,
        .@"enum",
        .@"fn",
        .error_set,
        => {
            if (actual != expected) {
                print("expected {any}, found {any}\n", .{ expected, actual });
                return error.TestExpectedEqual;
            }
        },

        .pointer => |pointer| {
            switch (pointer.size) {
                .one, .many, .c => {
                    if (actual != expected) {
                        print("expected {*}, found {*}\n", .{ expected, actual });
                        return error.TestExpectedEqual;
                    }
                },
                .slice => {
                    if (actual.ptr != expected.ptr) {
                        print("expected slice ptr {*}, found {*}\n", .{ expected.ptr, actual.ptr });
                        return error.TestExpectedEqual;
                    }
                    if (actual.len != expected.len) {
                        print("expected slice len {}, found {}\n", .{ expected.len, actual.len });
                        return error.TestExpectedEqual;
                    }
                },
            }
        },

        .array => |array| try expectEqualSlices(array.child, &expected, &actual),

        .vector => |info| {
            const expect_array: [info.len]info.child = expected;
            const actual_array: [info.len]info.child = actual;
            try expectEqualSlices(info.child, &expect_array, &actual_array);
        },

        .@"struct" => |@"struct"| {
            inline for (@"struct".field_names) |field_name| {
                try expectEqual(@field(expected, field_name), @field(actual, field_name));
            }
        },

        .@"union" => |@"union"| if (@"union".backing_integer) |Int| {
            try expectEqual(@as(Int, @bitCast(expected)), @as(Int, @bitCast(actual)));
        } else switch (@"union".layout) {
            .@"packed" => {
                const Int = @Int(.unsigned, @bitSizeOf(T));
                try expectEqual(@as(Int, @bitCast(expected)), @as(Int, @bitCast(actual)));
            },
            .@"extern" => {
                const first_size = @bitSizeOf(@"union".field_types[0]);
                inline for (@"union".field_types) |field_type| {
                    if (@bitSizeOf(field_type) != first_size) {
                        @compileError("Unable to compare extern unions with varying field sizes for type " ++ @typeName(T));
                    }
                }
                const FieldInt = @Int(.unsigned, first_size);
                const expected_field = @field(expected, @"union".field_names[0]);
                const actual_field = @field(actual, @"union".field_names[0]);
                return expectEqual(
                    @as(FieldInt, @bitCast(expected_field)),
                    @as(FieldInt, @bitCast(actual_field)),
                );
            },
            .auto => {
                const Tag = @"union".tag_type orelse @compileError("byteSwapAllFields expects packed, extern, or tagged union");

                try expectEqual(@as(Tag, expected), @as(Tag, actual));
                switch (expected) {
                    inline else => |expected_payload, tag| {
                        const actual_payload = @field(actual, @tagName(tag));
                        try expectEqual(expected_payload, actual_payload);
                    },
                }
            },
        },

        .optional => {
            if (expected) |expected_payload| {
                if (actual) |actual_payload| {
                    try expectEqual(expected_payload, actual_payload);
                } else {
                    print("expected {any}, found null\n", .{expected_payload});
                    return error.TestExpectedEqual;
                }
            } else {
                if (actual) |actual_payload| {
                    print("expected null, found {any}\n", .{actual_payload});
                    return error.TestExpectedEqual;
                }
            }
        },

        .error_union => {
            if (expected) |expected_payload| {
                if (actual) |actual_payload| {
                    try expectEqual(expected_payload, actual_payload);
                } else |actual_err| {
                    print("expected {any}, found {}\n", .{ expected_payload, actual_err });
                    return error.TestExpectedEqual;
                }
            } else |expected_err| {
                if (actual) |actual_payload| {
                    print("expected {}, found {any}\n", .{ expected_err, actual_payload });
                    return error.TestExpectedEqual;
                } else |actual_err| {
                    try expectEqual(expected_err, actual_err);
                }
            }
        },
    }
}