Something went wrong. Try again.
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253const std = @import("std");const uucode = @import("uucode");
// Old API-compatible Grapheme valuepub const Grapheme = struct { start: usize, len: usize,
pub fn bytes(self: Grapheme, str: []const u8) []const u8 { return str[self.start .. self.start + self.len]; }};
// Old API-compatible iterator that yields Grapheme with .len and .bytes()pub const GraphemeIterator = struct { str: []const u8, inner: uucode.grapheme.Iterator(uucode.utf8.Iterator),
pub fn init(str: []const u8) GraphemeIterator { return .{ .str = str, .inner = uucode.grapheme.utf8Iterator(str), }; }
pub fn next(self: *GraphemeIterator) ?Grapheme { const g = self.inner.nextGrapheme() orelse return null; return .{ .start = g.start, .len = g.end - g.start }; }};
/// creates a grapheme iterator based on strpub fn graphemeIterator(str: []const u8) GraphemeIterator { return GraphemeIterator.init(str);}
test { std.testing.refAllDecls(@This());}
test "grapheme iterator: invalid utf8 + combining mark" { // An invalid byte decodes to U+FFFD but consumes only one byte var it = graphemeIterator("ab\xff\xcc\x81"); try std.testing.expectEqual(Grapheme{ .start = 0, .len = 1 }, it.next().?); try std.testing.expectEqual(Grapheme{ .start = 1, .len = 1 }, it.next().?); try std.testing.expectEqual(Grapheme{ .start = 2, .len = 3 }, it.next().?); try std.testing.expectEqual(null, it.next());
it = graphemeIterator("\xff\xcc\x81"); try std.testing.expectEqual(Grapheme{ .start = 0, .len = 3 }, it.next().?); try std.testing.expectEqual(null, it.next());}