|
18 | 18 |
|
19 | 19 | // some utils to parser strings. |
20 | 20 | const std = @import("std"); |
21 | | -const testing = std.testing; |
22 | 21 |
|
23 | 22 | pub const Reader = struct { |
24 | | - s: []const u8, |
25 | | - i: usize = 0, |
| 23 | + pos: usize = 0, |
| 24 | + data: []const u8, |
26 | 25 |
|
27 | 26 | pub fn until(self: *Reader, c: u8) []const u8 { |
28 | | - const ln = self.s.len; |
29 | | - const start = self.i; |
30 | | - while (self.i < ln) { |
31 | | - if (c == self.s[self.i]) return self.s[start..self.i]; |
32 | | - self.i += 1; |
33 | | - } |
| 27 | + const pos = self.pos; |
| 28 | + const data = self.data; |
34 | 29 |
|
35 | | - return self.s[start..self.i]; |
| 30 | + const index = std.mem.indexOfScalarPos(u8, data, pos, c) orelse data.len; |
| 31 | + self.pos = index; |
| 32 | + return data[pos..index]; |
36 | 33 | } |
37 | 34 |
|
38 | 35 | pub fn tail(self: *Reader) []const u8 { |
39 | | - if (self.i > self.s.len) return ""; |
40 | | - defer self.i = self.s.len; |
41 | | - return self.s[self.i..]; |
| 36 | + const pos = self.pos; |
| 37 | + const data = self.data; |
| 38 | + if (pos > data.len) { |
| 39 | + return ""; |
| 40 | + } |
| 41 | + self.pos = data.len; |
| 42 | + return data[pos..]; |
42 | 43 | } |
43 | 44 |
|
44 | 45 | pub fn skip(self: *Reader) bool { |
45 | | - if (self.i >= self.s.len) return false; |
46 | | - self.i += 1; |
| 46 | + const pos = self.pos; |
| 47 | + if (pos >= self.data.len) { |
| 48 | + return false; |
| 49 | + } |
| 50 | + self.pos = pos + 1; |
47 | 51 | return true; |
48 | 52 | } |
49 | 53 | }; |
50 | 54 |
|
51 | | -test "Reader.skip" { |
52 | | - var r = Reader{ .s = "foo" }; |
53 | | - try testing.expect(r.skip()); |
54 | | - try testing.expect(r.skip()); |
55 | | - try testing.expect(r.skip()); |
56 | | - try testing.expect(!r.skip()); |
57 | | - try testing.expect(!r.skip()); |
| 55 | +const testing = std.testing; |
| 56 | +test "parser.Reader: skip" { |
| 57 | + var r = Reader{ .data = "foo" }; |
| 58 | + try testing.expectEqual(true, r.skip()); |
| 59 | + try testing.expectEqual(true, r.skip()); |
| 60 | + try testing.expectEqual(true, r.skip()); |
| 61 | + try testing.expectEqual(false, r.skip()); |
| 62 | + try testing.expectEqual(false, r.skip()); |
58 | 63 | } |
59 | 64 |
|
60 | | -test "Reader.tail" { |
61 | | - var r = Reader{ .s = "foo" }; |
| 65 | +test "parser.Reader: tail" { |
| 66 | + var r = Reader{ .data = "foo" }; |
62 | 67 | try testing.expectEqualStrings("foo", r.tail()); |
63 | 68 | try testing.expectEqualStrings("", r.tail()); |
| 69 | + try testing.expectEqualStrings("", r.tail()); |
64 | 70 | } |
65 | 71 |
|
66 | | -test "Reader.until" { |
67 | | - var r = Reader{ .s = "foo.bar.baz" }; |
| 72 | +test "parser.Reader: until" { |
| 73 | + var r = Reader{ .data = "foo.bar.baz" }; |
68 | 74 | try testing.expectEqualStrings("foo", r.until('.')); |
69 | 75 | _ = r.skip(); |
70 | 76 | try testing.expectEqualStrings("bar", r.until('.')); |
71 | 77 | _ = r.skip(); |
72 | 78 | try testing.expectEqualStrings("baz", r.until('.')); |
73 | 79 |
|
74 | | - r = Reader{ .s = "foo" }; |
| 80 | + r = Reader{ .data = "foo" }; |
75 | 81 | try testing.expectEqualStrings("foo", r.until('.')); |
| 82 | + try testing.expectEqualStrings("", r.tail()); |
76 | 83 |
|
77 | | - r = Reader{ .s = "" }; |
| 84 | + r = Reader{ .data = "" }; |
78 | 85 | try testing.expectEqualStrings("", r.until('.')); |
79 | | -} |
80 | | - |
81 | | -pub fn trim(s: []const u8) []const u8 { |
82 | | - const ln = s.len; |
83 | | - if (ln == 0) { |
84 | | - return ""; |
85 | | - } |
86 | | - var start: usize = 0; |
87 | | - while (start < ln) { |
88 | | - if (!std.ascii.isWhitespace(s[start])) break; |
89 | | - start += 1; |
90 | | - } |
91 | | - |
92 | | - var end: usize = ln; |
93 | | - while (end > 0) { |
94 | | - if (!std.ascii.isWhitespace(s[end - 1])) break; |
95 | | - end -= 1; |
96 | | - } |
97 | | - |
98 | | - return s[start..end]; |
99 | | -} |
100 | | - |
101 | | -test "trim" { |
102 | | - try testing.expectEqualStrings("", trim("")); |
103 | | - try testing.expectEqualStrings("foo", trim("foo")); |
104 | | - try testing.expectEqualStrings("foo", trim(" \n\tfoo")); |
105 | | - try testing.expectEqualStrings("foo", trim("foo \n\t")); |
| 86 | + try testing.expectEqualStrings("", r.tail()); |
106 | 87 | } |
0 commit comments