Function next [src]
After each call to this function, and on deinit(), the memory returned
from this function becomes invalid. A copy must be made in order to keep
a reference to the path.
Prototype
pub fn next(self: *Walker) !?Walker.Entry
Parameters
self: *Walker
Source
pub fn next(self: *Walker) !?Walker.Entry {
const gpa = self.allocator;
while (self.stack.items.len != 0) {
// `top` and `containing` become invalid after appending to `self.stack`
var top = &self.stack.items[self.stack.items.len - 1];
var containing = top;
var dirname_len = top.dirname_len;
if (top.iter.next() catch |err| {
// If we get an error, then we want the user to be able to continue
// walking if they want, which means that we need to pop the directory
// that errored from the stack. Otherwise, all future `next` calls would
// likely just fail with the same error.
var item = self.stack.pop().?;
if (self.stack.items.len != 0) {
item.iter.dir.close();
}
return err;
}) |base| {
self.name_buffer.shrinkRetainingCapacity(dirname_len);
if (self.name_buffer.items.len != 0) {
try self.name_buffer.append(gpa, fs.path.sep);
dirname_len += 1;
}
try self.name_buffer.ensureUnusedCapacity(gpa, base.name.len + 1);
self.name_buffer.appendSliceAssumeCapacity(base.name);
self.name_buffer.appendAssumeCapacity(0);
if (base.kind == .directory) {
var new_dir = top.iter.dir.openDir(base.name, .{ .iterate = true }) catch |err| switch (err) {
error.NameTooLong => unreachable, // no path sep in base.name
else => |e| return e,
};
{
errdefer new_dir.close();
try self.stack.append(gpa, .{
.iter = new_dir.iterateAssumeFirstIteration(),
.dirname_len = self.name_buffer.items.len - 1,
});
top = &self.stack.items[self.stack.items.len - 1];
containing = &self.stack.items[self.stack.items.len - 2];
}
}
return .{
.dir = containing.iter.dir,
.basename = self.name_buffer.items[dirname_len .. self.name_buffer.items.len - 1 :0],
.path = self.name_buffer.items[0 .. self.name_buffer.items.len - 1 :0],
.kind = base.kind,
};
} else {
var item = self.stack.pop().?;
if (self.stack.items.len != 0) {
item.iter.dir.close();
}
}
}
return null;
}