| ... | @@ -435,7 +435,7 @@ pub fn defaultSpec(comptime T: type) [:0]const u8 { | ... | @@ -435,7 +435,7 @@ pub fn defaultSpec(comptime T: type) [:0]const u8 { |
| 435 | .Array => |_| return ANY, | 435 | .Array => |_| return ANY, |
| 436 | .Pointer => |ptr_info| switch (ptr_info.size) { | 436 | .Pointer => |ptr_info| switch (ptr_info.size) { |
| 437 | .One => switch (@typeInfo(ptr_info.child)) { | 437 | .One => switch (@typeInfo(ptr_info.child)) { |
| 438 | .Array => |_| return "*", | 438 | .Array => |_| return ANY, |
| 439 | else => {}, | 439 | else => {}, |
| 440 | }, | 440 | }, |
| 441 | .Many, .C => return "*", | 441 | .Many, .C => return "*", |
| ... | @@ -599,26 +599,7 @@ pub fn formatType( | ... | @@ -599,26 +599,7 @@ pub fn formatType( |
| 599 | }, | 599 | }, |
| 600 | .Pointer => |ptr_info| switch (ptr_info.size) { | 600 | .Pointer => |ptr_info| switch (ptr_info.size) { |
| 601 | .One => switch (@typeInfo(ptr_info.child)) { | 601 | .One => switch (@typeInfo(ptr_info.child)) { |
| 602 | .Array => |info| { | 602 | .Array, .Enum, .Union, .Struct => { |
| 603 | if (actual_fmt.len == 0) | | |
| 604 | @compileError("cannot format array ref without a specifier (i.e. {s} or {*})"); | | |
| 605 | if (info.child == u8) { | | |
| 606 | switch (actual_fmt[0]) { | | |
| 607 | 's', 'x', 'X', 'e', 'E' => { | | |
| 608 | comptime checkTextFmt(actual_fmt); | | |
| 609 | return formatBuf(value, options, writer); | | |
| 610 | }, | | |
| 611 | else => {}, | | |
| 612 | } | | |
| 613 | } | | |
| 614 | for (value, 0..) |item, i| { | | |
| 615 | comptime checkTextFmt(actual_fmt); | | |
| 616 | if (i != 0) try formatBuf(", ", options, writer); | | |
| 617 | try formatBuf(item, options, writer); | | |
| 618 | } | | |
| 619 | return; | | |
| 620 | }, | | |
| 621 | .Enum, .Union, .Struct => { | | |
| 622 | return formatType(value.*, actual_fmt, options, writer, max_depth); | 603 | return formatType(value.*, actual_fmt, options, writer, max_depth); |
| 623 | }, | 604 | }, |
| 624 | else => return format(writer, "{s}@{x}", .{ @typeName(ptr_info.child), @intFromPtr(value) }), | 605 | else => return format(writer, "{s}@{x}", .{ @typeName(ptr_info.child), @intFromPtr(value) }), |
| ... | @@ -629,14 +610,8 @@ pub fn formatType( | ... | @@ -629,14 +610,8 @@ pub fn formatType( |
| 629 | if (ptr_info.sentinel) |_| { | 610 | if (ptr_info.sentinel) |_| { |
| 630 | return formatType(mem.span(value), actual_fmt, options, writer, max_depth); | 611 | return formatType(mem.span(value), actual_fmt, options, writer, max_depth); |
| 631 | } | 612 | } |
| 632 | if (ptr_info.child == u8) { | 613 | if (actual_fmt[0] == 's' and ptr_info.child == u8) { |
| 633 | switch (actual_fmt[0]) { | 614 | return formatBuf(mem.span(value), options, writer); |
| 634 | 's', 'x', 'X', 'e', 'E' => { | | |
| 635 | comptime checkTextFmt(actual_fmt); | | |
| 636 | return formatBuf(mem.span(value), options, writer); | | |
| 637 | }, | | |
| 638 | else => {}, | | |
| 639 | } | | |
| 640 | } | 615 | } |
| 641 | invalidFmtError(fmt, value); | 616 | invalidFmtError(fmt, value); |
| 642 | }, | 617 | }, |
| ... | @@ -646,14 +621,8 @@ pub fn formatType( | ... | @@ -646,14 +621,8 @@ pub fn formatType( |
| 646 | if (max_depth == 0) { | 621 | if (max_depth == 0) { |
| 647 | return writer.writeAll("{ ... }"); | 622 | return writer.writeAll("{ ... }"); |
| 648 | } | 623 | } |
| 649 | if (ptr_info.child == u8) { | 624 | if (actual_fmt[0] == 's' and ptr_info.child == u8) { |
| 650 | switch (actual_fmt[0]) { | 625 | return formatBuf(value, options, writer); |
| 651 | 's', 'x', 'X', 'e', 'E' => { | | |
| 652 | comptime checkTextFmt(actual_fmt); | | |
| 653 | return formatBuf(value, options, writer); | | |
| 654 | }, | | |
| 655 | else => {}, | | |
| 656 | } | | |
| 657 | } | 626 | } |
| 658 | try writer.writeAll("{ "); | 627 | try writer.writeAll("{ "); |
| 659 | for (value, 0..) |elem, i| { | 628 | for (value, 0..) |elem, i| { |
| ... | @@ -671,14 +640,8 @@ pub fn formatType( | ... | @@ -671,14 +640,8 @@ pub fn formatType( |
| 671 | if (max_depth == 0) { | 640 | if (max_depth == 0) { |
| 672 | return writer.writeAll("{ ... }"); | 641 | return writer.writeAll("{ ... }"); |
| 673 | } | 642 | } |
| 674 | if (info.child == u8) { | 643 | if (actual_fmt[0] == 's' and info.child == u8) { |
| 675 | switch (actual_fmt[0]) { | 644 | return formatBuf(&value, options, writer); |
| 676 | 's', 'x', 'X', 'e', 'E' => { | | |
| 677 | comptime checkTextFmt(actual_fmt); | | |
| 678 | return formatBuf(&value, options, writer); | | |
| 679 | }, | | |
| 680 | else => {}, | | |
| 681 | } | | |
| 682 | } | 645 | } |
| 683 | try writer.writeAll("{ "); | 646 | try writer.writeAll("{ "); |
| 684 | for (value, 0..) |elem, i| { | 647 | for (value, 0..) |elem, i| { |
| ... | @@ -2205,12 +2168,22 @@ test "buffer" { | ... | @@ -2205,12 +2168,22 @@ test "buffer" { |
| 2205 | } | 2168 | } |
| 2206 | } | 2169 | } |
| 2207 | | 2170 | |
| | 2171 | // Test formatting of arrays by value, by single-item pointer, and as a slice |
| | 2172 | fn expectArrayFmt(expected: []const u8, comptime template: []const u8, comptime array_value: anytype) !void { |
| | 2173 | try expectFmt(expected, template, .{array_value}); |
| | 2174 | try expectFmt(expected, template, .{&array_value}); |
| | 2175 | var runtime_zero: usize = 0; |
| | 2176 | _ = &runtime_zero; |
| | 2177 | try expectFmt(expected, template, .{array_value[runtime_zero..]}); |
| | 2178 | } |
| | 2179 | |
| 2208 | test "array" { | 2180 | test "array" { |
| 2209 | { | 2181 | { |
| 2210 | const value: [3]u8 = "abc".*; | 2182 | const value: [3]u8 = "abc".*; |
| 2211 | try expectFmt("array: abc\n", "array: {s}\n", .{value}); | 2183 | try expectArrayFmt("array: abc\n", "array: {s}\n", value); |
| 2212 | try expectFmt("array: abc\n", "array: {s}\n", .{&value}); | 2184 | try expectArrayFmt("array: { 97, 98, 99 }\n", "array: {d}\n", value); |
| 2213 | try expectFmt("array: { 97, 98, 99 }\n", "array: {d}\n", .{value}); | 2185 | try expectArrayFmt("array: { 61, 62, 63 }\n", "array: {x}\n", value); |
| | 2186 | try expectArrayFmt("array: { 97, 98, 99 }\n", "array: {any}\n", value); |
| 2214 | | 2187 | |
| 2215 | var buf: [100]u8 = undefined; | 2188 | var buf: [100]u8 = undefined; |
| 2216 | try expectFmt( | 2189 | try expectFmt( |
| ... | @@ -2219,12 +2192,23 @@ test "array" { | ... | @@ -2219,12 +2192,23 @@ test "array" { |
| 2219 | .{&value}, | 2192 | .{&value}, |
| 2220 | ); | 2193 | ); |
| 2221 | } | 2194 | } |
| | 2195 | |
| | 2196 | { |
| | 2197 | const value = [2][3]u8{ "abc".*, "def".* }; |
| | 2198 | |
| | 2199 | try expectArrayFmt("array: { abc, def }\n", "array: {s}\n", value); |
| | 2200 | try expectArrayFmt("array: { { 97, 98, 99 }, { 100, 101, 102 } }\n", "array: {d}\n", value); |
| | 2201 | try expectArrayFmt("array: { { 61, 62, 63 }, { 64, 65, 66 } }\n", "array: {x}\n", value); |
| | 2202 | } |
| 2222 | } | 2203 | } |
| 2223 | | 2204 | |
| 2224 | test "slice" { | 2205 | test "slice" { |
| 2225 | { | 2206 | { |
| 2226 | const value: []const u8 = "abc"; | 2207 | const value: []const u8 = "abc"; |
| 2227 | try expectFmt("slice: abc\n", "slice: {s}\n", .{value}); | 2208 | try expectFmt("slice: abc\n", "slice: {s}\n", .{value}); |
| | 2209 | try expectFmt("slice: { 97, 98, 99 }\n", "slice: {d}\n", .{value}); |
| | 2210 | try expectFmt("slice: { 61, 62, 63 }\n", "slice: {x}\n", .{value}); |
| | 2211 | try expectFmt("slice: { 97, 98, 99 }\n", "slice: {any}\n", .{value}); |
| 2228 | } | 2212 | } |
| 2229 | { | 2213 | { |
| 2230 | var runtime_zero: usize = 0; | 2214 | var runtime_zero: usize = 0; |