Skip to content

Commit 894a991

Browse files
committed
Add depth function to Walker.Entry
This enables depth-related use cases without any dependency on the Walker's internal stack which doesn't always pertain to the actual depth of the current entry (i.e. recursing into a directory immediately affects the stack).
1 parent 98dd885 commit 894a991

File tree

3 files changed

+28
-20
lines changed

3 files changed

+28
-20
lines changed

lib/std/fs/Dir.zig

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -732,16 +732,14 @@ pub const SelectiveWalker = struct {
732732
});
733733
}
734734

735-
pub fn depth(self: *SelectiveWalker) usize {
736-
return self.stack.items.len;
737-
}
738-
739735
pub fn deinit(self: *SelectiveWalker) void {
740736
self.name_buffer.deinit(self.allocator);
741737
self.stack.deinit(self.allocator);
742738
}
743739

744740
/// Leaves the current directory, continuing walking one level up.
741+
/// If the current entry is a directory entry, then the "current directory"
742+
/// will pertain to that entry if `enter` is called before `leave`.
745743
pub fn leave(self: *SelectiveWalker) void {
746744
var item = self.stack.pop().?;
747745
if (self.stack.items.len != 0) {
@@ -789,6 +787,13 @@ pub const Walker = struct {
789787
basename: [:0]const u8,
790788
path: [:0]const u8,
791789
kind: Dir.Entry.Kind,
790+
791+
/// Returns the depth of the entry relative to the initial directory.
792+
/// Returns 1 for a direct child of the initial directory, 2 for an entry
793+
/// within a direct child of the initial directory, etc.
794+
pub fn depth(self: Walker.Entry) usize {
795+
return mem.countScalar(u8, self.path, fs.path.sep) + 1;
796+
}
792797
};
793798

794799
const StackItem = struct {

lib/std/fs/test.zig

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,14 +1765,14 @@ test "walker" {
17651765

17661766
// iteration order of walker is undefined, so need lookup maps to check against
17671767

1768-
const expected_paths = std.StaticStringMap(void).initComptime(.{
1769-
.{"dir1"},
1770-
.{"dir2"},
1771-
.{"dir3"},
1772-
.{"dir4"},
1773-
.{"dir3" ++ fs.path.sep_str ++ "sub1"},
1774-
.{"dir3" ++ fs.path.sep_str ++ "sub2"},
1775-
.{"dir3" ++ fs.path.sep_str ++ "sub2" ++ fs.path.sep_str ++ "subsub1"},
1768+
const expected_paths = std.StaticStringMap(usize).initComptime(.{
1769+
.{ "dir1", 1 },
1770+
.{ "dir2", 1 },
1771+
.{ "dir3", 1 },
1772+
.{ "dir4", 1 },
1773+
.{ "dir3" ++ fs.path.sep_str ++ "sub1", 2 },
1774+
.{ "dir3" ++ fs.path.sep_str ++ "sub2", 2 },
1775+
.{ "dir3" ++ fs.path.sep_str ++ "sub2" ++ fs.path.sep_str ++ "subsub1", 3 },
17761776
});
17771777

17781778
const expected_basenames = std.StaticStringMap(void).initComptime(.{
@@ -1802,6 +1802,10 @@ test "walker" {
18021802
std.debug.print("found unexpected path: {f}\n", .{std.ascii.hexEscape(entry.path, .lower)});
18031803
return err;
18041804
};
1805+
testing.expectEqual(expected_paths.get(entry.path).?, entry.depth()) catch |err| {
1806+
std.debug.print("path reported unexpected depth: {f}\n", .{std.ascii.hexEscape(entry.path, .lower)});
1807+
return err;
1808+
};
18051809
// make sure that the entry.dir is the containing dir
18061810
var entry_dir = try entry.dir.openDir(entry.basename, .{});
18071811
defer entry_dir.close();
@@ -1851,6 +1855,10 @@ test "selective walker, skip entries that start with ." {
18511855
var num_walked: usize = 0;
18521856
while (try walker.next()) |entry| {
18531857
if (entry.basename[0] == '.') continue;
1858+
if (entry.kind == .directory) {
1859+
try walker.enter(entry);
1860+
}
1861+
18541862
testing.expect(expected_basenames.has(entry.basename)) catch |err| {
18551863
std.debug.print("found unexpected basename: {f}\n", .{std.ascii.hexEscape(entry.basename, .lower)});
18561864
return err;
@@ -1859,16 +1867,11 @@ test "selective walker, skip entries that start with ." {
18591867
std.debug.print("found unexpected path: {f}\n", .{std.ascii.hexEscape(entry.path, .lower)});
18601868
return err;
18611869
};
1862-
1863-
testing.expectEqual(expected_paths.get(entry.path).?, walker.depth()) catch |err| {
1864-
std.debug.print("path reported unexpected depth: {f}, {d}, expected {d}\n", .{ std.ascii.hexEscape(entry.path, .lower), walker.depth(), expected_paths.get(entry.path).? });
1870+
testing.expectEqual(expected_paths.get(entry.path).?, entry.depth()) catch |err| {
1871+
std.debug.print("path reported unexpected depth: {f}\n", .{std.ascii.hexEscape(entry.path, .lower)});
18651872
return err;
18661873
};
18671874

1868-
if (entry.kind == .directory) {
1869-
try walker.enter(entry);
1870-
}
1871-
18721875
// make sure that the entry.dir is the containing dir
18731876
var entry_dir = try entry.dir.openDir(entry.basename, .{});
18741877
defer entry_dir.close();

tools/update_mingw.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ pub fn main() !void {
117117
while (try walker.next()) |entry| {
118118
switch (entry.kind) {
119119
.directory => {
120-
switch (walker.depth()) {
120+
switch (entry.depth()) {
121121
1 => if (def_dirs.has(entry.basename)) {
122122
try walker.enter(entry);
123123
continue;

0 commit comments

Comments
 (0)