summaryrefslogtreecommitdiff
path: root/src/estd/cursor.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/estd/cursor.zig')
-rw-r--r--src/estd/cursor.zig69
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));
+}