| ... | @@ -153,6 +153,15 @@ pub fn utf8Decode4(bytes: []const u8) Utf8Decode4Error!u21 { | ... | @@ -153,6 +153,15 @@ pub fn utf8Decode4(bytes: []const u8) Utf8Decode4Error!u21 { |
| 153 | return value; | 153 | return value; |
| 154 | } | 154 | } |
| 155 | | 155 | |
| | 156 | /// Returns true if the given unicode codepoint can be encoded in UTF-8. |
| | 157 | pub fn utf8ValidCodepoint(value: u21) bool { |
| | 158 | return switch (value) { |
| | 159 | 0xD800...0xDFFF => false, // Surrogates range |
| | 160 | 0x110000...0x1FFFFF => false, // Above the maximum codepoint value |
| | 161 | else => true, |
| | 162 | }; |
| | 163 | } |
| | 164 | |
| 156 | /// Returns the length of a supplied UTF-8 string literal in terms of unicode | 165 | /// Returns the length of a supplied UTF-8 string literal in terms of unicode |
| 157 | /// codepoints. | 166 | /// codepoints. |
| 158 | /// Asserts that the data is valid UTF-8. | 167 | /// Asserts that the data is valid UTF-8. |
| ... | @@ -785,3 +794,19 @@ test "utf8 count codepoints" { | ... | @@ -785,3 +794,19 @@ test "utf8 count codepoints" { |
| 785 | try testUtf8CountCodepoints(); | 794 | try testUtf8CountCodepoints(); |
| 786 | comptime testUtf8CountCodepoints() catch unreachable; | 795 | comptime testUtf8CountCodepoints() catch unreachable; |
| 787 | } | 796 | } |
| | 797 | |
| | 798 | fn testUtf8ValidCodepoint() !void { |
| | 799 | testing.expect(utf8ValidCodepoint('e')); |
| | 800 | testing.expect(utf8ValidCodepoint('ë')); |
| | 801 | testing.expect(utf8ValidCodepoint('は')); |
| | 802 | testing.expect(utf8ValidCodepoint(0xe000)); |
| | 803 | testing.expect(utf8ValidCodepoint(0x10ffff)); |
| | 804 | testing.expect(!utf8ValidCodepoint(0xd800)); |
| | 805 | testing.expect(!utf8ValidCodepoint(0xdfff)); |
| | 806 | testing.expect(!utf8ValidCodepoint(0x110000)); |
| | 807 | } |
| | 808 | |
| | 809 | test "utf8 valid codepoint" { |
| | 810 | try testUtf8ValidCodepoint(); |
| | 811 | comptime testUtf8ValidCodepoint() catch unreachable; |
| | 812 | } |