diff options
| author | LemonBoy <thatlemon@gmail.com> | 2020-09-21 16:14:47 +0200 |
|---|---|---|
| committer | LemonBoy <thatlemon@gmail.com> | 2020-11-05 16:10:34 +0100 |
| commit | 0316ac959c1435eba4c63579feb0dced05fba366 (patch) | |
| tree | 74e454b639a4499b90977f17bc56660166581cf8 /lib | |
| parent | 675de8d6b723aa4be6a51e7f371364799dd7491b (diff) | |
| download | zig-0316ac959c1435eba4c63579feb0dced05fba366.tar.gz zig-0316ac959c1435eba4c63579feb0dced05fba366.zip | |
Make std.formatBuf UTF-8 aware
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/std/fmt.zig | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 8e4f0993d9..d449e85c9a 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -672,25 +672,34 @@ pub fn formatBuf( options: FormatOptions, writer: anytype, ) !void { - const width = options.width orelse buf.len; - const padding = if (width > buf.len) (width - buf.len) else 0; - - switch (options.alignment) { - .Left => { - try writer.writeAll(buf); - try writer.writeByteNTimes(options.fill, padding); - }, - .Center => { - const left_padding = padding / 2; - const right_padding = (padding + 1) / 2; - try writer.writeByteNTimes(options.fill, left_padding); - try writer.writeAll(buf); - try writer.writeByteNTimes(options.fill, right_padding); - }, - .Right => { - try writer.writeByteNTimes(options.fill, padding); - try writer.writeAll(buf); - }, + if (options.width) |min_width| { + // In case of error assume the buffer content is ASCII-encoded + const width = unicode.utf8CountCodepoints(buf) catch |_| buf.len; + const padding = if (width < min_width) min_width - width else 0; + + if (padding == 0) + return writer.writeAll(buf); + + switch (options.alignment) { + .Left => { + try writer.writeAll(buf); + try writer.writeByteNTimes(options.fill, padding); + }, + .Center => { + const left_padding = padding / 2; + const right_padding = (padding + 1) / 2; + try writer.writeByteNTimes(options.fill, left_padding); + try writer.writeAll(buf); + try writer.writeByteNTimes(options.fill, right_padding); + }, + .Right => { + try writer.writeByteNTimes(options.fill, padding); + try writer.writeAll(buf); + }, + } + } else { + // Fast path, avoid counting the number of codepoints + try writer.writeAll(buf); } } @@ -1442,6 +1451,10 @@ test "int.padded" { try testFmt("i16: '-12345'", "i16: '{:4}'", .{@as(i16, -12345)}); try testFmt("i16: '+12345'", "i16: '{:4}'", .{@as(i16, 12345)}); try testFmt("u16: '12345'", "u16: '{:4}'", .{@as(u16, 12345)}); + + try testFmt("UTF-8: 'ü '", "UTF-8: '{u:<4}'", .{'ü'}); + try testFmt("UTF-8: ' ü'", "UTF-8: '{u:>4}'", .{'ü'}); + try testFmt("UTF-8: ' ü '", "UTF-8: '{u:^4}'", .{'ü'}); } test "buffer" { @@ -1971,6 +1984,9 @@ test "padding" { try testFmt("==================Filled", "{:=>24}", .{"Filled"}); try testFmt(" Centered ", "{:^24}", .{"Centered"}); try testFmt("-", "{:-^1}", .{""}); + try testFmt("==crêpe===", "{:=^10}", .{"crêpe"}); + try testFmt("=====crêpe", "{:=>10}", .{"crêpe"}); + try testFmt("crêpe=====", "{:=<10}", .{"crêpe"}); } test "decimal float padding" { |
