diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index b45194a83741..b623765aa2a8 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -11,6 +11,7 @@ const unicode = std.unicode; const meta = std.meta; const lossyCast = math.lossyCast; const expectFmt = std.testing.expectFmt; +const testing = std.testing; pub const default_max_depth = 3; @@ -315,7 +316,6 @@ pub const Specifier = union(enum) { /// Allows to implement formatters compatible with std.fmt without replicating /// the standard library behavior. pub const Parser = struct { - pos: usize = 0, iter: std.unicode.Utf8Iterator, // Returns a decimal number or null if the current character is not a @@ -341,13 +341,13 @@ pub const Parser = struct { // Returns a substring of the input starting from the current position // and ending where `ch` is found or until the end if not found pub fn until(self: *@This(), ch: u21) []const u8 { - var result: []const u8 = &[_]u8{}; + const start = self.iter.i; while (self.peek(0)) |code_point| { if (code_point == ch) break; - result = result ++ (self.iter.nextCodepointSlice() orelse &[_]u8{}); + _ = self.iter.nextCodepoint(); } - return result; + return self.iter.bytes[start..self.iter.i]; } // Returns one character, if available @@ -2763,3 +2763,47 @@ test hex { try std.testing.expectEqualStrings("[00efcdab78563412]", s); } } + +test "parser until" { + { // return substring till ':' + var parser: Parser = .{ + .iter = .{ .bytes = "abc:1234", .i = 0 }, + }; + try testing.expectEqualStrings("abc", parser.until(':')); + } + + { // return the entire string - `ch` not found + var parser: Parser = .{ + .iter = .{ .bytes = "abc1234", .i = 0 }, + }; + try testing.expectEqualStrings("abc1234", parser.until(':')); + } + + { // substring is empty - `ch` is the only character + var parser: Parser = .{ + .iter = .{ .bytes = ":", .i = 0 }, + }; + try testing.expectEqualStrings("", parser.until(':')); + } + + { // empty string and `ch` not found + var parser: Parser = .{ + .iter = .{ .bytes = "", .i = 0 }, + }; + try testing.expectEqualStrings("", parser.until(':')); + } + + { // substring starts at index 2 and goes upto `ch` + var parser: Parser = .{ + .iter = .{ .bytes = "abc:1234", .i = 2 }, + }; + try testing.expectEqualStrings("c", parser.until(':')); + } + + { // substring starts at index 4 and goes upto the end - `ch` not found + var parser: Parser = .{ + .iter = .{ .bytes = "abc1234", .i = 4 }, + }; + try testing.expectEqualStrings("234", parser.until(':')); + } +}