Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion lib/std/fmt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -530,8 +530,10 @@ pub fn formatIntValue(
} else if (comptime std.mem.eql(u8, fmt, "c")) {
if (@TypeOf(int_value).bit_count <= 8) {
return formatAsciiChar(@as(u8, int_value), options, out_stream);
} else if (@TypeOf(int_value).bit_count <= 32) {
return formatUnicodeCodepoint(@as(u21, int_value), options, out_stream);
} else {
@compileError("Cannot print integer that is larger than 8 bits as a ascii");
@compileError("Cannot print character that is larger than 21 bits as unicode codepoint");
}
} else if (comptime std.mem.eql(u8, fmt, "b")) {
radix = 2;
Expand Down Expand Up @@ -590,6 +592,19 @@ pub fn formatAsciiChar(
return out_stream.writeAll(@as(*const [1]u8, &c));
}

pub fn formatUnicodeCodepoint(
c: u21,
options: FormatOptions,
out_stream: var,
) !void {
var result: [4]u8 = undefined;
const len = std.unicode.utf8Encode(c, &result) catch |e| switch (e) {
error.CodepointTooLarge => return out_stream.writeAll("<codepoint too large>"),
error.Utf8CannotEncodeSurrogateHalf => return out_stream.writeAll("<invalid codepoint>"),
};
return out_stream.writeAll(result[0..len]);
}

pub fn formatBuf(
buf: []const u8,
options: FormatOptions,
Expand Down Expand Up @@ -1197,6 +1212,14 @@ test "int.specifier" {
const value: u8 = 'a';
try testFmt("u8: a\n", "u8: {c}\n", .{value});
}
{
const value: u21 = 'あ';
try testFmt("codepoint: あ\n", "codepoint: {c}\n", .{value});
}
{
const value: u21 = 2097151;
try testFmt("codepoint: <codepoint too large>\n", "codepoint: {c}\n", .{value});
}
{
const value: u8 = 0b1100;
try testFmt("u8: 0b1100\n", "u8: 0b{b}\n", .{value});
Expand Down