1 module isodi.internal;
2 
3 import std.string;
4 
5 
6 package @safe:
7 
8 
9 /// Iterate on file ancestors, starting from and including the requested file and ending on the root.
10 struct DeepAncestors {
11 
12     const string path;
13 
14     int opApply(int delegate(string) @trusted dg) {
15 
16         auto dir = path[];
17 
18         while (dir.length) {
19 
20             // Remove trailing slashes
21             dir = dir.stripRight("/");
22 
23             // Yield the content
24             auto result = dg(dir);
25             if (result) return result;
26 
27             // Get the position on which the segment ends
28             auto segmentEnd = dir.lastIndexOf("/");
29 
30             // Stop if this is the last segment
31             if (segmentEnd == -1) break;
32 
33             // Remove last path segment
34             dir = dir[0 .. segmentEnd];
35 
36         }
37 
38         // Push empty path
39         return dg("");
40 
41     }
42 
43 }
44 
45 /// Iterate on file ancestors starting from root, ending on and including the file itself.
46 struct Ancestors {
47 
48     const wstring path;
49 
50     int opApply(int delegate(wstring) @trusted dg) {
51 
52         wstring current;
53 
54         auto result = dg(""w);
55         if (result) return result;
56 
57         // Check each value
58         foreach (ch; path) {
59 
60             // Encountered a path separator
61             if (ch == '/' || ch == '\\') {
62 
63                 // Yield the current values
64                 result = dg(current);
65                 if (result) return result;
66                 current ~= "/";
67 
68             }
69 
70             // Add the character
71             else current ~= ch;
72 
73         }
74 
75         // Yield the full path
76         if (current.length && current[$-1] != '/') {
77 
78             result = dg(current);
79             return result;
80 
81         }
82 
83         return 0;
84 
85     }
86 
87 }