diff options
author | Mathias Magnusson <mathias@magnusson.space> | 2025-05-28 23:00:32 +0200 |
---|---|---|
committer | Mathias Magnusson <mathias@magnusson.space> | 2025-05-28 23:00:32 +0200 |
commit | 7b85276fc98643b1138df6f322b8bd657339ea96 (patch) | |
tree | 3d36e1d4961f92caa0fe0e00bb8e27a0fd1242b5 /src/peek.zig | |
download | huginn-7b85276fc98643b1138df6f322b8bd657339ea96.tar.gz |
initial commit
Diffstat (limited to 'src/peek.zig')
-rw-r--r-- | src/peek.zig | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/peek.zig b/src/peek.zig new file mode 100644 index 0000000..58911e9 --- /dev/null +++ b/src/peek.zig @@ -0,0 +1,51 @@ +pub fn peekable(iterator: anytype) Peekable(@TypeOf(iterator)) { + return .{ .iterator = iterator }; +} + +pub fn Peekable(Iterator: type) type { + const ActualIterator = switch (@typeInfo(Iterator)) { + .pointer => |p| p.child, + else => Iterator, + }; + const Next = @typeInfo(@TypeOf(ActualIterator.next)).@"fn"; + const Item = switch (@typeInfo(Next.return_type.?)) { + .optional => |o| o.child, + else => |i| i, + }; + return struct { + iterator: Iterator, + peeked: ?Item = null, + + pub fn peek(self: *Self) ?Item { + if (self.peeked) |peeked| return peeked; + const item = self.iterator.next(); + self.peeked = item; + return item; + } + + pub fn next(self: *Self) ?Item { + const item = if (self.peeked) |peeked| peeked else self.iterator.next(); + self.peeked = null; + return item; + } + + const Self = @This(); + }; +} + +test peekable { + const expect = std.testing.expect; + // std.meta.de + + var it = std.mem.window(u8, &[_]u8{ 1, 2, 3 }, 1, 1); + var peek = peekable(&it); + try expect(peek.next().?[0] == 1); + try expect(peek.peek().?[0] == 2); + try expect(peek.peek().?[0] == 2); + try expect(peek.next().?[0] == 2); + try expect(peek.next().?[0] == 3); + try expect(peek.peek() == null); + try expect(peek.next() == null); +} + +const std = @import("std"); |