From de5c25420b05aab47346a7cd4c8d9def85b9d0f9 Mon Sep 17 00:00:00 2001 From: nyx-xyn Date: Tue, 28 Jul 2026 21:01:34 +0200 Subject: [PATCH] std.unicode: add peekCodepoint (#31038) Adds peekCodepoint() to Utf8Iterator and Wtf8Iterator. Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31038 Reviewed-by: Ryan Liptak --- lib/std/unicode.zig | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/lib/std/unicode.zig b/lib/std/unicode.zig index 259e46d685bcfc00fc118e8b4cd95f47bdb3869f..a6cd094800cc0a77fcd84394bc08736df7352b0f 100644 --- a/lib/std/unicode.zig +++ b/lib/std/unicode.zig @@ -425,6 +425,15 @@ pub const Utf8Iterator = struct { return it.bytes[original_i..end_ix]; } + + /// Look ahead at the next codepoint without advancing the iterator. + /// If no codepoints exist, then returns null. + pub fn peekCodepoint(it: *Utf8Iterator) ?u21 { + const original_i = it.i; + defer it.i = original_i; + + return it.nextCodepoint(); + } }; pub fn utf16IsHighSurrogate(c: u16) bool { @@ -768,6 +777,9 @@ fn testMiscInvalidUtf8() !void { test "utf8 iterator peeking" { try comptime testUtf8Peeking(); try testUtf8Peeking(); + + comptime try testUtf8PeekCodepoint(); + try testUtf8PeekCodepoint(); } fn testUtf8Peeking() !void { @@ -790,6 +802,20 @@ fn testUtf8Peeking() !void { try testing.expect(mem.eql(u8, &[_]u8{}, it.peek(1))); } +fn testUtf8PeekCodepoint() !void { + const s = Utf8View.initComptime("東京市"); + var it = s.iterator(); + + try testing.expect(it.peekCodepoint().? == 0x6771); + try testing.expect(it.peekCodepoint().? == 0x6771); + _ = it.nextCodepoint(); + try testing.expect(it.peekCodepoint().? == 0x4eac); + _ = it.nextCodepoint(); + try testing.expect(it.peekCodepoint().? == 0x5e02); + _ = it.nextCodepoint(); + try testing.expect(it.peekCodepoint() == null); +} + fn testError(bytes: []const u8, expected_err: anyerror) !void { try testing.expectError(expected_err, testDecode(bytes)); } @@ -1758,6 +1784,15 @@ pub const Wtf8Iterator = struct { return it.bytes[original_i..end_ix]; } + + /// Look ahead at the next codepoint without advancing the iterator. + /// If no codepoints exist, then returns null. + pub fn peekCodepoint(it: *Wtf8Iterator) ?u21 { + const original_i = it.i; + defer it.i = original_i; + + return it.nextCodepoint(); + } }; pub fn wtf16LeToWtf8ArrayList(result: *std.array_list.Managed(u8), utf16le: []const u16) Allocator.Error!void { -- 2.54.0