Skip to content

Instantly share code, notes, and snippets.

@matu3ba
Created January 22, 2023 01:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matu3ba/e1ab29ddaf1254375c42c5e62f6defb2 to your computer and use it in GitHub Desktop.
Save matu3ba/e1ab29ddaf1254375c42c5e62f6defb2 to your computer and use it in GitHub Desktop.
Count Steps to Directory With Entry as diff file
diff --git a/lib/std/fs.zig b/lib/std/fs.zig
index 31354a278..f06db4943 100644
--- a/lib/std/fs.zig
+++ b/lib/std/fs.zig
@@ -2085,6 +2085,44 @@ pub const Dir = struct {
}
}
+ pub const CountStepsToFolderWithEntryError = error{
+ InvalidKind,
+ SearchedFileNotFound,
+ } || std.fs.Dir.Iterator.Error || std.fs.Dir.OpenError;
+
+ /// Traverse folders upwards upwards until finding an entry with content `match`
+ /// Returns number of upwards traversals.
+ /// 0 indicates that the file is in the current directory
+ /// assert: dir was opened with iterate permissions
+ pub fn countStepsToFolderWithEntry(
+ self: Dir,
+ match: []const u8,
+ kind: File.Kind,
+ ) CountStepsToFolderWithEntryError!u32 {
+ var cnt_up: u32 = 0;
+ var diriter: Dir = undefined;
+ var dirparent: Dir = self;
+ while (true) {
+ diriter = dirparent;
+ defer diriter.close();
+ var iter = diriter.iterate();
+ while (try iter.next()) |entry| {
+ if (std.mem.eql(u8, entry.name, match)) {
+ if (entry.kind != kind)
+ return error.InvalidKind;
+ return cnt_up;
+ }
+ }
+ dirparent = diriter.openDir("..", .{ .no_follow = true, .iterate = true }) catch |err| {
+ switch (err) {
+ error.AccessDenied => return error.SearchedFileNotFound,
+ else => return err,
+ }
+ };
+ cnt_up += 1;
+ }
+ }
+
/// Writes content to the file system, creating a new file if it does not exist, truncating
/// if it already exists.
pub fn writeFile(self: Dir, sub_path: []const u8, data: []const u8) !void {
diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig
index f4003c180..35dbdd57e 100644
--- a/lib/std/fs/test.zig
+++ b/lib/std/fs/test.zig
@@ -1221,3 +1221,16 @@ test "File.PermissionsUnix" {
try testing.expect(permissions_unix.unixHas(.user, .execute));
try testing.expect(!permissions_unix.unixHas(.other, .execute));
}
+
+test "Dir.countStepsToFolderWithEntry" {
+ const build_zig = "build.zig";
+ var tmp = std.testing.tmpDir(.{ .no_follow = true, .iterate = true });
+ defer tmp.cleanup();
+ _ = try tmp.dir.createFile(build_zig, .{});
+ var subdir = try tmp.dir.makeOpenPath("sub/sub/sub/sub/sub", .{
+ .no_follow = true,
+ .iterate = true,
+ });
+ const lvlups = try subdir.countStepsToFolderWithEntry(build_zig, .File);
+ try testing.expect(lvlups == @as(u32, 5));
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment