aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLemonBoy <thatlemon@gmail.com>2020-09-21 16:14:47 +0200
committerLemonBoy <thatlemon@gmail.com>2020-11-05 16:10:34 +0100
commit0316ac959c1435eba4c63579feb0dced05fba366 (patch)
tree74e454b639a4499b90977f17bc56660166581cf8
parent675de8d6b723aa4be6a51e7f371364799dd7491b (diff)
downloadzig-0316ac959c1435eba4c63579feb0dced05fba366.tar.gz
zig-0316ac959c1435eba4c63579feb0dced05fba366.zip
Make std.formatBuf UTF-8 aware
-rw-r--r--lib/std/fmt.zig54
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" {