Created
March 10, 2021 08:50
-
-
Save slimsag/8f098a13177b4bc008a7741505819f90 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
const Allocator = std.mem.Allocator; | |
const Parser = @import("parser.zig").Parser; | |
const Error = @import("parser.zig").Error; | |
pub fn Literal(comptime Reader: type) type { | |
return struct { | |
parser: Parser([]u8, Reader) = .{ | |
._parse = parse, | |
}, | |
want: []const u8, | |
const Self = @This(); | |
pub fn init(want: []const u8) Self { | |
return Self{ | |
.want = want | |
}; | |
} | |
fn parse(parser: *Parser([]u8, Reader), allocator: *Allocator, src: *Reader) callconv(.Inline) Error!?[]u8 { | |
const self = @fieldParentPtr(Self, "parser", parser); | |
const buf = try allocator.alloc(u8, self.want.len); | |
const read = try src.reader().readAll(buf); | |
if (read < self.want.len or !std.mem.eql(u8, buf, self.want)) { | |
try src.seekableStream().seekBy(-@intCast(i64, read)); | |
allocator.free(buf); | |
return null; | |
} | |
return buf; | |
} | |
}; | |
} | |
test "literal" { | |
const allocator = std.testing.allocator; | |
var reader = std.io.fixedBufferStream("abcdef"); | |
var want: []const u8 = "abc"; | |
var literal = Literal(@TypeOf(reader)).init(want); | |
const p = &literal.parser; | |
var result = try p.parse(allocator, &reader); | |
std.testing.expectEqualStrings(want, result.?); | |
if (result) |r| { | |
allocator.free(r); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
const Allocator = std.mem.Allocator; | |
pub const Error = error{ | |
EndOfStream, | |
Utf8InvalidStartByte, | |
} || std.fs.File.ReadError || std.fs.File.SeekError || std.mem.Allocator.Error; | |
pub fn Parser(comptime Value: type, comptime Reader: type) type { | |
return struct { | |
const Self = @This(); | |
_parse: fn(self: *Self, allocator: *Allocator, src: *Reader) callconv(.Inline) Error!?Value, | |
pub fn parse(self: *Self, allocator: *Allocator, src: *Reader) callconv(.Inline) Error!?Value { | |
return self._parse(self, allocator, src); | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment