lib/sys/src/path.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 const capabilities = @import("capabilities.zig");
 3 
 4 pub const required_capabilities = capabilities.pure();
 5 
 6 pub const separator = std.fs.path.sep;
 7 
 8 pub fn join(
 9     allocator: std.mem.Allocator,
10     parts: []const []const u8,
11 ) std.mem.Allocator.Error![]u8 {
12     return std.fs.path.join(allocator, parts);
13 }
14 
15 pub fn dirname(path: []const u8) ?[]const u8 {
16     return std.fs.path.dirname(path);
17 }
18 
19 pub fn basename(path: []const u8) []const u8 {
20     return std.fs.path.basename(path);
21 }
22 
23 pub fn extension(path: []const u8) []const u8 {
24     return std.fs.path.extension(path);
25 }
26 
27 pub fn isAbsolute(path: []const u8) bool {
28     return std.fs.path.isAbsolute(path);
29 }
30 
31 pub fn trimTrailingSeparators(path: []const u8) []const u8 {
32     var end = path.len;
33     while (end > 1 and isSeparator(path[end - 1])) : (end -= 1) {}
34     return path[0..end];
35 }
36 
37 pub fn isSeparator(byte: u8) bool {
38     return std.fs.path.isSep(byte);
39 }
40 
41 test "trimTrailingSeparators preserves root" {
42     try std.testing.expectEqualStrings("/", trimTrailingSeparators("/"));
43     try std.testing.expectEqualStrings("/tmp/tiny", trimTrailingSeparators("/tmp/tiny///"));
44 }
45 
46 test "path parts expose std path policy" {
47     try std.testing.expectEqualStrings("file.zig", basename("/tmp/file.zig"));
48     try std.testing.expectEqualStrings(".zig", extension("/tmp/file.zig"));
49     try std.testing.expect(isAbsolute("/tmp"));
50 }