Commit 4f6981bbe3
Changed files (1)
lib
std
lib/std/Ini.zig
@@ -0,0 +1,66 @@
+bytes: []const u8,
+
+pub const SectionIterator = struct {
+ ini: Ini,
+ next_index: ?usize,
+ header: []const u8,
+
+ pub fn next(it: *SectionIterator) ?[]const u8 {
+ const bytes = it.ini.bytes;
+ const start = it.next_index orelse return null;
+ const end = mem.indexOfPos(u8, bytes, start, "\n[") orelse bytes.len;
+ const result = bytes[start..end];
+ if (mem.indexOfPos(u8, bytes, start, it.header)) |next_index| {
+ it.next_index = next_index + it.header.len;
+ } else {
+ it.next_index = null;
+ }
+ return result;
+ }
+};
+
+/// Asserts that `header` includes "\n[" at the beginning and "]\n" at the end.
+/// `header` must remain valid for the lifetime of the iterator.
+pub fn iterateSection(ini: Ini, header: []const u8) SectionIterator {
+ assert(mem.startsWith(u8, header, "\n["));
+ assert(mem.endsWith(u8, header, "]\n"));
+ const first_header = header[1..];
+ const next_index = if (mem.indexOf(u8, ini.bytes, first_header)) |i|
+ i + first_header.len
+ else
+ null;
+ return .{
+ .ini = ini,
+ .next_index = next_index,
+ .header = header,
+ };
+}
+
+const std = @import("std.zig");
+const mem = std.mem;
+const assert = std.debug.assert;
+const Ini = @This();
+const testing = std.testing;
+
+test iterateSection {
+ const example =
+ \\[package]
+ \\name=libffmpeg
+ \\version=5.1.2
+ \\
+ \\[dependency]
+ \\id=libz
+ \\url=url1
+ \\
+ \\[dependency]
+ \\id=libmp3lame
+ \\url=url2
+ ;
+ var ini: Ini = .{ .bytes = example };
+ var it = ini.iterateSection("\n[dependency]\n");
+ const section1 = it.next() orelse return error.TestFailed;
+ try testing.expectEqualStrings("id=libz\nurl=url1\n", section1);
+ const section2 = it.next() orelse return error.TestFailed;
+ try testing.expectEqualStrings("id=libmp3lame\nurl=url2", section2);
+ try testing.expect(it.next() == null);
+}