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]; } }