authorgravatar for mrees@noeontheend.comMichael Rees <mrees@noeontheend.com> 2020-06-17 06:04:08-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-18 20:35:03-04:00
logbd17a373cc20c919be9fa279a4420033e959ca92
treef902f2b494b5bc820d93d88fb5109b5815ebfa63
parent5ea0f589c92018b4596ebbbd5e0ce3b71467585c

Add std.unicode.Utf8Iterator.peek


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

lib/std/unicode.zig+41
...@@ -235,6 +235,22 @@ pub const Utf8Iterator = struct {...@@ -235,6 +235,22 @@ pub const Utf8Iterator = struct {
235 else => unreachable,235 else => unreachable,
236 }236 }
237 }237 }
238
239 /// Look ahead at the next n codepoints without advancing the iterator.
240 /// If fewer than n codepoints are available, then return the remainder of the string.
241 pub fn peek(it: *Utf8Iterator, n: usize) []const u8 {
242 const original_i = it.i;
243 defer it.i = original_i;
244
245 var end_ix = original_i;
246 var found: usize = 0;
247 while (found < n) : (found += 1) {
248 const next_codepoint = it.nextCodepointSlice() orelse return it.bytes[original_i..];
249 end_ix += next_codepoint.len;
250 }
251
252 return it.bytes[original_i..end_ix];
253 }
238};254};
239255
240pub const Utf16LeIterator = struct {256pub const Utf16LeIterator = struct {
...@@ -451,6 +467,31 @@ fn testMiscInvalidUtf8() void {...@@ -451,6 +467,31 @@ fn testMiscInvalidUtf8() void {
451 testValid("\xee\x80\x80", 0xe000);467 testValid("\xee\x80\x80", 0xe000);
452}468}
453469
470test "utf8 iterator peeking" {
471 comptime testUtf8Peeking();
472 testUtf8Peeking();
473}
474
475fn testUtf8Peeking() void {
476 const s = Utf8View.initComptime("noël");
477 var it = s.iterator();
478
479 testing.expect(std.mem.eql(u8, "n", it.nextCodepointSlice().?));
480
481 testing.expect(std.mem.eql(u8, "o", it.peek(1)));
482 testing.expect(std.mem.eql(u8, "oë", it.peek(2)));
483 testing.expect(std.mem.eql(u8, "oël", it.peek(3)));
484 testing.expect(std.mem.eql(u8, "oël", it.peek(4)));
485 testing.expect(std.mem.eql(u8, "oël", it.peek(10)));
486
487 testing.expect(std.mem.eql(u8, "o", it.nextCodepointSlice().?));
488 testing.expect(std.mem.eql(u8, "ë", it.nextCodepointSlice().?));
489 testing.expect(std.mem.eql(u8, "l", it.nextCodepointSlice().?));
490 testing.expect(it.nextCodepointSlice() == null);
491
492 testing.expect(std.mem.eql(u8, &[_]u8{}, it.peek(1)));
493}
494
454fn testError(bytes: []const u8, expected_err: anyerror) void {495fn testError(bytes: []const u8, expected_err: anyerror) void {
455 testing.expectError(expected_err, testDecode(bytes));496 testing.expectError(expected_err, testDecode(bytes));
456}497}