| ... | ... | @@ -76,6 +76,7 @@ fn peekIsAlign(comptime fmt: []const u8) bool { |
| 76 | 76 | /// - `b`: output integer value in binary notation |
| 77 | 77 | /// - `o`: output integer value in octal notation |
| 78 | 78 | /// - `c`: output integer as an ASCII character. Integer type must have 8 bits at max. |
| 79 | /// - `u`: output integer as an UTF-8 sequence. Integer type must have 32 bits at max. |
| 79 | 80 | /// - `*`: output the address of the value instead of the value itself. |
| 80 | 81 | /// |
| 81 | 82 | /// If a formatted user type contains a function of the type |
| ... | ... | @@ -555,6 +556,12 @@ pub fn formatIntValue( |
| 555 | 556 | } else { |
| 556 | 557 | @compileError("Cannot escape character with more than 8 bits"); |
| 557 | 558 | } |
| 559 | } else if (comptime std.mem.eql(u8, fmt, "u")) { |
| 560 | if (@TypeOf(int_value).bit_count <= 32) { |
| 561 | return formatUtf8Codepoint(@as(u32, int_value), options, context, Errors, output); |
| 562 | } else { |
| 563 | @compileError("Cannot print integer that is larger than 32 bits as an UTF-8 sequence"); |
| 564 | } |
| 558 | 565 | } else if (comptime std.mem.eql(u8, fmt, "b")) { |
| 559 | 566 | radix = 2; |
| 560 | 567 | uppercase = false; |
| ... | ... | @@ -641,6 +648,18 @@ pub fn formatAsciiChar( |
| 641 | 648 | return writer.writeAll(@as(*const [1]u8, &c)); |
| 642 | 649 | } |
| 643 | 650 | |
| 651 | pub fn formatUtf8Codepoint( |
| 652 | c: u32, |
| 653 | options: FormatOptions, |
| 654 | context: anytype, |
| 655 | comptime Errors: type, |
| 656 | output: fn (@TypeOf(context), []const u8) Errors!void, |
| 657 | ) Errors!void { |
| 658 | var buf: [4]u8 = undefined; |
| 659 | const len = std.unicode.utf8Encode(c, buf[0..]) catch unreachable; |
| 660 | return output(context, @as(*const [4]u8, &buf)[0..len]); |
| 661 | } |
| 662 | |
| 644 | 663 | pub fn formatBuf( |
| 645 | 664 | buf: []const u8, |
| 646 | 665 | options: FormatOptions, |
| ... | ... | @@ -1385,6 +1404,14 @@ test "int.specifier" { |
| 1385 | 1404 | const value: u16 = 0o1234; |
| 1386 | 1405 | try testFmt("u16: 0o1234\n", "u16: 0o{o}\n", .{value}); |
| 1387 | 1406 | } |
| 1407 | { |
| 1408 | const value: u8 = 'a'; |
| 1409 | try testFmt("UTF-8: a\n", "UTF-8: {u}\n", .{value}); |
| 1410 | } |
| 1411 | { |
| 1412 | const value: u32 = 0x1F310; |
| 1413 | try testFmt("UTF-8: 🌐\n", "UTF-8: {u}\n", .{value}); |
| 1414 | } |
| 1388 | 1415 | } |
| 1389 | 1416 | |
| 1390 | 1417 | test "int.padded" { |