diff options
Diffstat (limited to 'src/estd/cursor.zig')
| -rw-r--r-- | src/estd/cursor.zig | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/estd/cursor.zig b/src/estd/cursor.zig new file mode 100644 index 0000000..c0a4a32 --- /dev/null +++ b/src/estd/cursor.zig @@ -0,0 +1,69 @@ +const std = @import("std"); + +pub const ReadError = error { + EndOfBuffer +}; + +pub fn Cursor(comptime T: type) type { + return struct { + const Self = @This(); + + buffer: []const T, + index: usize, + touched_index: usize, + + pub fn init(buffer: []const T) Self { + return .{ + .buffer = buffer, + .index = 0, + .touched_index = 0, + }; + } + + pub fn peek(self: Self, amount: usize) ReadError![]const T { + if (self.index + amount > self.buffer.len) { + return ReadError.EndOfBuffer; + } + + return self.buffer[self.index..self.index + amount]; + } + + pub fn consume(self: *Self, amount: usize) ReadError![]const T { + const slice = try self.peek(amount); + self.index += amount; + self.touched_index = self.index; + return slice; + } + + pub fn snapshot(self: Self) usize { + return self.index; + } + + pub fn rollback(self: *Self, index: usize) void { + self.index = index; + } + + pub fn touched_slice(self: Self) []const T { + return self.buffer[0..self.touched_index]; + } + }; +} + +test "peek" { + const buffer = "1234"; + const cursor = Cursor(u8).init(buffer); + try std.testing.expectEqualSlices(u8, "1", try cursor.peek(1)); + try std.testing.expectEqualSlices(u8, "12", try cursor.peek(2)); + try std.testing.expectEqualSlices(u8, "123", try cursor.peek(3)); + try std.testing.expectEqualSlices(u8, "1234", try cursor.peek(4)); + try std.testing.expectError(ReadError.EndOfBuffer, cursor.peek(5)); +} + +test "consume" { + const buffer = "12345678"; + var cursor = Cursor(u8).init(buffer); + try std.testing.expectEqualSlices(u8, "1", try cursor.consume(1)); + try std.testing.expectEqualSlices(u8, "23", try cursor.consume(2)); + try std.testing.expectEqualSlices(u8, "456", try cursor.consume(3)); + try std.testing.expectError(ReadError.EndOfBuffer, cursor.consume(4)); +} |