authorgravatar for nyx-xyn@nyru.xyznyx-xyn <nyx-xyn@nyru.xyz> 2026-07-28 21:01:34+02:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2026-07-28 21:01:34+02:00
logde5c25420b05aab47346a7cd4c8d9def85b9d0f9
treef3b756c1f561b1c88e65dc468004a4ce99ba5a62
parent4e5ce9909a7a008ca6a4a4fb9c45c473f95c9a8c

std.unicode: add peekCodepoint (#31038)

Adds peekCodepoint() to Utf8Iterator and Wtf8Iterator. Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31038 Reviewed-by: Ryan Liptak <squeek502@noreply.codeberg.org>

1 files changed, 35 insertions(+), 0 deletions(-)

lib/std/unicode.zig+35
...@@ -425,6 +425,15 @@ pub const Utf8Iterator = struct {...@@ -425,6 +425,15 @@ pub const Utf8Iterator = struct {
425425
426 return it.bytes[original_i..end_ix];426 return it.bytes[original_i..end_ix];
427 }427 }
428
429 /// Look ahead at the next codepoint without advancing the iterator.
430 /// If no codepoints exist, then returns null.
431 pub fn peekCodepoint(it: *Utf8Iterator) ?u21 {
432 const original_i = it.i;
433 defer it.i = original_i;
434
435 return it.nextCodepoint();
436 }
428};437};
429438
430pub fn utf16IsHighSurrogate(c: u16) bool {439pub fn utf16IsHighSurrogate(c: u16) bool {
...@@ -768,6 +777,9 @@ fn testMiscInvalidUtf8() !void {...@@ -768,6 +777,9 @@ fn testMiscInvalidUtf8() !void {
768test "utf8 iterator peeking" {777test "utf8 iterator peeking" {
769 try comptime testUtf8Peeking();778 try comptime testUtf8Peeking();
770 try testUtf8Peeking();779 try testUtf8Peeking();
780
781 comptime try testUtf8PeekCodepoint();
782 try testUtf8PeekCodepoint();
771}783}
772784
773fn testUtf8Peeking() !void {785fn testUtf8Peeking() !void {
...@@ -790,6 +802,20 @@ fn testUtf8Peeking() !void {...@@ -790,6 +802,20 @@ fn testUtf8Peeking() !void {
790 try testing.expect(mem.eql(u8, &[_]u8{}, it.peek(1)));802 try testing.expect(mem.eql(u8, &[_]u8{}, it.peek(1)));
791}803}
792804
805fn testUtf8PeekCodepoint() !void {
806 const s = Utf8View.initComptime("東京市");
807 var it = s.iterator();
808
809 try testing.expect(it.peekCodepoint().? == 0x6771);
810 try testing.expect(it.peekCodepoint().? == 0x6771);
811 _ = it.nextCodepoint();
812 try testing.expect(it.peekCodepoint().? == 0x4eac);
813 _ = it.nextCodepoint();
814 try testing.expect(it.peekCodepoint().? == 0x5e02);
815 _ = it.nextCodepoint();
816 try testing.expect(it.peekCodepoint() == null);
817}
818
793fn testError(bytes: []const u8, expected_err: anyerror) !void {819fn testError(bytes: []const u8, expected_err: anyerror) !void {
794 try testing.expectError(expected_err, testDecode(bytes));820 try testing.expectError(expected_err, testDecode(bytes));
795}821}
...@@ -1758,6 +1784,15 @@ pub const Wtf8Iterator = struct {...@@ -1758,6 +1784,15 @@ pub const Wtf8Iterator = struct {
17581784
1759 return it.bytes[original_i..end_ix];1785 return it.bytes[original_i..end_ix];
1760 }1786 }
1787
1788 /// Look ahead at the next codepoint without advancing the iterator.
1789 /// If no codepoints exist, then returns null.
1790 pub fn peekCodepoint(it: *Wtf8Iterator) ?u21 {
1791 const original_i = it.i;
1792 defer it.i = original_i;
1793
1794 return it.nextCodepoint();
1795 }
1761};1796};
17621797
1763pub fn wtf16LeToWtf8ArrayList(result: *std.array_list.Managed(u8), utf16le: []const u16) Allocator.Error!void {1798pub fn wtf16LeToWtf8ArrayList(result: *std.array_list.Managed(u8), utf16le: []const u16) Allocator.Error!void {