struct Parser [src]
A stream based parser for format strings.
Allows to implement formatters compatible with std.fmt without replicating
the standard library behavior.
Fields
bytes: []const u8
i: usize
Members
Source
pub const Parser = struct {
bytes: []const u8,
i: usize,
pub fn number(self: *@This()) ?usize {
var r: ?usize = null;
while (self.peek(0)) |byte| {
switch (byte) {
'0'...'9' => {
if (r == null) r = 0;
r.? *= 10;
r.? += byte - '0';
},
else => break,
}
self.i += 1;
}
return r;
}
pub fn until(self: *@This(), delimiter: u8) []const u8 {
const start = self.i;
self.i = std.mem.indexOfScalarPos(u8, self.bytes, self.i, delimiter) orelse self.bytes.len;
return self.bytes[start..self.i];
}
pub fn char(self: *@This()) ?u8 {
const i = self.i;
if (self.bytes.len - i == 0) return null;
self.i = i + 1;
return self.bytes[i];
}
pub fn maybe(self: *@This(), byte: u8) bool {
if (self.peek(0) == byte) {
self.i += 1;
return true;
}
return false;
}
pub fn specifier(self: *@This()) !Specifier {
if (self.maybe('[')) {
const arg_name = self.until(']');
if (!self.maybe(']')) return error.@"Expected closing ]";
return .{ .named = arg_name };
}
if (self.number()) |i| return .{ .number = i };
return .{ .none = {} };
}
pub fn peek(self: *@This(), i: usize) ?u8 {
const peek_index = self.i + i;
if (peek_index >= self.bytes.len) return null;
return self.bytes[peek_index];
}
}