Created
January 22, 2023 01:59
-
-
Save matu3ba/e1ab29ddaf1254375c42c5e62f6defb2 to your computer and use it in GitHub Desktop.
Count Steps to Directory With Entry as diff file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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