mirror of
https://github.com/ziglang/zig.git
synced 2024-11-28 08:02:32 +00:00
std.fmt: fix formatting slices of structs with custom formatting
`hasMethod` doesn't make sense for pointers to more than one item.
This commit is contained in:
parent
122387943b
commit
6030855097
@ -2255,6 +2255,24 @@ test "slice" {
|
||||
try expectFmt("int: { 1, 1000, 5fad3, 423a35c7 }", "int: {x}", .{int_slice[runtime_zero..]});
|
||||
try expectFmt("int: { 00001, 01000, 5fad3, 423a35c7 }", "int: {x:0>5}", .{int_slice[runtime_zero..]});
|
||||
}
|
||||
{
|
||||
const S1 = struct {
|
||||
x: u8,
|
||||
};
|
||||
const struct_slice: []const S1 = &[_]S1{ S1{ .x = 8 }, S1{ .x = 42 } };
|
||||
try expectFmt("slice: { fmt.test.slice.S1{ .x = 8 }, fmt.test.slice.S1{ .x = 42 } }", "slice: {any}", .{struct_slice});
|
||||
}
|
||||
{
|
||||
const S2 = struct {
|
||||
x: u8,
|
||||
|
||||
pub fn format(s: @This(), comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
try writer.print("S2({})", .{s.x});
|
||||
}
|
||||
};
|
||||
const struct_slice: []const S2 = &[_]S2{ S2{ .x = 8 }, S2{ .x = 42 } };
|
||||
try expectFmt("slice: { S2(8), S2(42) }", "slice: {any}", .{struct_slice});
|
||||
}
|
||||
}
|
||||
|
||||
test "escape non-printable" {
|
||||
|
@ -1122,15 +1122,66 @@ pub inline fn hasFn(comptime T: type, comptime name: []const u8) bool {
|
||||
return @typeInfo(@TypeOf(@field(T, name))) == .Fn;
|
||||
}
|
||||
|
||||
test "hasFn" {
|
||||
const S1 = struct {
|
||||
pub fn foo() void {}
|
||||
};
|
||||
|
||||
try std.testing.expect(hasFn(S1, "foo"));
|
||||
try std.testing.expect(!hasFn(S1, "bar"));
|
||||
try std.testing.expect(!hasFn(*S1, "foo"));
|
||||
|
||||
const S2 = struct {
|
||||
foo: fn () void,
|
||||
};
|
||||
|
||||
try std.testing.expect(!hasFn(S2, "foo"));
|
||||
}
|
||||
|
||||
/// Returns true if a type has a `name` method; `false` otherwise.
|
||||
/// Result is always comptime-known.
|
||||
pub inline fn hasMethod(comptime T: type, comptime name: []const u8) bool {
|
||||
return switch (@typeInfo(T)) {
|
||||
.Pointer => |P| hasFn(P.child, name),
|
||||
.Pointer => |P| switch (P.size) {
|
||||
.One => hasFn(P.child, name),
|
||||
.Many, .Slice, .C => false,
|
||||
},
|
||||
else => hasFn(T, name),
|
||||
};
|
||||
}
|
||||
|
||||
test "hasMethod" {
|
||||
try std.testing.expect(!hasMethod(u32, "foo"));
|
||||
try std.testing.expect(!hasMethod([]u32, "len"));
|
||||
try std.testing.expect(!hasMethod(struct { u32, u64 }, "len"));
|
||||
|
||||
const S1 = struct {
|
||||
pub fn foo() void {}
|
||||
};
|
||||
|
||||
try std.testing.expect(hasMethod(S1, "foo"));
|
||||
try std.testing.expect(hasMethod(*S1, "foo"));
|
||||
|
||||
try std.testing.expect(!hasMethod(S1, "bar"));
|
||||
try std.testing.expect(!hasMethod(*[1]S1, "foo"));
|
||||
try std.testing.expect(!hasMethod(*[10]S1, "foo"));
|
||||
try std.testing.expect(!hasMethod([]S1, "foo"));
|
||||
|
||||
const S2 = struct {
|
||||
foo: fn () void,
|
||||
};
|
||||
|
||||
try std.testing.expect(!hasMethod(S2, "foo"));
|
||||
|
||||
const U = union {
|
||||
pub fn foo() void {}
|
||||
};
|
||||
|
||||
try std.testing.expect(hasMethod(U, "foo"));
|
||||
try std.testing.expect(hasMethod(*U, "foo"));
|
||||
try std.testing.expect(!hasMethod(U, "bar"));
|
||||
}
|
||||
|
||||
/// True if every value of the type `T` has a unique bit pattern representing it.
|
||||
/// In other words, `T` has no unused bits and no padding.
|
||||
/// Result is always comptime-known.
|
||||
|
Loading…
Reference in New Issue
Block a user