diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2025-01-25 04:47:33 +0000 |
|---|---|---|
| committer | mlugg <mlugg@mlugg.co.uk> | 2025-01-25 04:48:00 +0000 |
| commit | 5202c977d95bf65775e733264b7d37ed940a2997 (patch) | |
| tree | 8cbe3d64aeae8e0493ae22df84fe77bcd42facb3 /lib/std | |
| parent | 921725427efeae591793f49291807a41112ccbf9 (diff) | |
| download | zig-5202c977d95bf65775e733264b7d37ed940a2997.tar.gz zig-5202c977d95bf65775e733264b7d37ed940a2997.zip | |
std: add `fs.path.fmtJoin`
This allows joining paths without allocating using a `Writer`.
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/fs/path.zig | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/lib/std/fs/path.zig b/lib/std/fs/path.zig index 3376771313..b2f95a937f 100644 --- a/lib/std/fs/path.zig +++ b/lib/std/fs/path.zig @@ -18,7 +18,6 @@ const debug = std.debug; const assert = debug.assert; const testing = std.testing; const mem = std.mem; -const fmt = std.fmt; const ascii = std.ascii; const Allocator = mem.Allocator; const math = std.math; @@ -147,6 +146,36 @@ pub fn joinZ(allocator: Allocator, paths: []const []const u8) ![:0]u8 { return out[0 .. out.len - 1 :0]; } +pub fn fmtJoin(paths: []const []const u8) std.fmt.Formatter(formatJoin) { + return .{ .data = paths }; +} + +fn formatJoin(paths: []const []const u8, comptime fmt: []const u8, options: std.fmt.FormatOptions, w: anytype) !void { + _ = fmt; + _ = options; + + const first_path_idx = for (paths, 0..) |p, idx| { + if (p.len != 0) break idx; + } else return; + + try w.writeAll(paths[first_path_idx]); // first component + var prev_path = paths[first_path_idx]; + for (paths[first_path_idx + 1 ..]) |this_path| { + if (this_path.len == 0) continue; // skip empty components + const prev_sep = isSep(prev_path[prev_path.len - 1]); + const this_sep = isSep(this_path[0]); + if (!prev_sep and !this_sep) { + try w.writeByte(sep); + } + if (prev_sep and this_sep) { + try w.writeAll(this_path[1..]); // skip redundant separator + } else { + try w.writeAll(this_path); + } + prev_path = this_path; + } +} + fn testJoinMaybeZUefi(paths: []const []const u8, expected: []const u8, zero: bool) !void { const uefiIsSep = struct { fn isSep(byte: u8) bool { |
