fediglam/src/util/iters.zig

74 lines
2.0 KiB
Zig

const std = @import("std");
pub fn Separator(comptime separator: u8) type {
return struct {
const Self = @This();
str: []const u8,
pub fn from(str: []const u8) Self {
return .{ .str = std.mem.trim(u8, str, &.{separator}) };
}
pub fn next(self: *Self) ?[]const u8 {
if (self.str.len == 0) return null;
const part = std.mem.sliceTo(self.str, separator);
self.str = std.mem.trimLeft(u8, self.str[part.len..], &.{separator});
return part;
}
};
}
pub const PathIter = struct {
is_first: bool,
iter: std.mem.SplitIterator(u8),
pub fn from(path: []const u8) PathIter {
return .{ .is_first = true, .iter = std.mem.split(u8, path, "/") };
}
pub fn next(self: *PathIter) ?[]const u8 {
defer self.is_first = false;
while (self.iter.next()) |it| if (it.len != 0) {
return it;
};
if (self.is_first) return self.iter.rest();
return null;
}
pub fn first(self: *PathIter) []const u8 {
std.debug.assert(self.is_first);
return self.next().?;
}
pub fn rest(self: *PathIter) []const u8 {
return self.iter.rest();
}
};
test "PathIter /ab/cd/" {
const path = "/ab/cd/";
var it = PathIter.from(path);
try std.testing.expectEqualStrings("ab", it.next().?);
try std.testing.expectEqualStrings("cd", it.next().?);
try std.testing.expectEqual(@as(?[]const u8, null), it.next());
}
test "PathIter ''" {
const path = "";
var it = PathIter.from(path);
try std.testing.expectEqualStrings("", it.next().?);
try std.testing.expectEqual(@as(?[]const u8, null), it.next());
}
test "PathIter ab/c//defg/" {
const path = "ab/c//defg/";
var it = PathIter.from(path);
try std.testing.expectEqualStrings("ab", it.next().?);
try std.testing.expectEqualStrings("c", it.next().?);
try std.testing.expectEqualStrings("defg", it.next().?);
try std.testing.expectEqual(@as(?[]const u8, null), it.next());
}