diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-12-11 19:32:21 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-11 19:32:21 -0500 |
| commit | 1852dc7e13b49a0b3238b8d654d09c4fc91aa3e4 (patch) | |
| tree | 1898f8a94bcf06b0c6cf45a30c8497fcadac8c6b /lib/std/fs | |
| parent | c4f53d1ef65b7942383471876e02a1bd03d37dd9 (diff) | |
| parent | b3af2f68b38c542f7d8bb5b1292c5301a07f9cac (diff) | |
| download | zig-1852dc7e13b49a0b3238b8d654d09c4fc91aa3e4.tar.gz zig-1852dc7e13b49a0b3238b8d654d09c4fc91aa3e4.zip | |
Merge pull request #7098 from MasterQ32/std.fs.path.extension
Implements std.fs.path.extension
Diffstat (limited to 'lib/std/fs')
| -rw-r--r-- | lib/std/fs/path.zig | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/std/fs/path.zig b/lib/std/fs/path.zig index 1bf2211372..8f1aaee554 100644 --- a/lib/std/fs/path.zig +++ b/lib/std/fs/path.zig @@ -28,6 +28,7 @@ pub const delimiter_windows = ';'; pub const delimiter_posix = ':'; pub const delimiter = if (builtin.os.tag == .windows) delimiter_windows else delimiter_posix; +/// Returns if the given byte is a valid path separator pub fn isSep(byte: u8) bool { if (builtin.os.tag == .windows) { return byte == '/' or byte == '\\'; @@ -1188,3 +1189,70 @@ fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []cons defer testing.allocator.free(result); testing.expectEqualSlices(u8, expected_output, result); } + +/// Returns the extension of the file name (if any). +/// This function will search for the file extension (separated by a `.`) and will return the text after the `.`. +/// Files that end with `.` are considered to have no extension, files that start with `.` +/// Examples: +/// - `"main.zig"` ⇒ `".zig"` +/// - `"src/main.zig"` ⇒ `".zig"` +/// - `".gitignore"` ⇒ `""` +/// - `"keep."` ⇒ `""` +/// - `"src.keep.me"` ⇒ `".me"` +/// - `"/src/keep.me"` ⇒ `".me"` +/// - `"/src/keep.me/"` ⇒ `".me"` +pub fn extension(path: []const u8) []const u8 { + const filename = basename(path); + return if (std.mem.lastIndexOf(u8, filename, ".")) |index| + if (index == 0 or index == filename.len - 1) + "" + else + filename[index..] + else + ""; +} + +fn testExtension(path: []const u8, expected: []const u8) void { + std.testing.expectEqualStrings(expected, extension(path)); +} + +test "extension" { + testExtension("", ""); + testExtension(".", ""); + testExtension("a.", ""); + testExtension("abc.", ""); + testExtension(".a", ""); + testExtension(".file", ""); + testExtension(".gitignore", ""); + testExtension("file.ext", ".ext"); + testExtension("file.ext.", ""); + testExtension("very-long-file.bruh", ".bruh"); + testExtension("a.b.c", ".c"); + testExtension("a.b.c/", ".c"); + + testExtension("/", ""); + testExtension("/.", ""); + testExtension("/a.", ""); + testExtension("/abc.", ""); + testExtension("/.a", ""); + testExtension("/.file", ""); + testExtension("/.gitignore", ""); + testExtension("/file.ext", ".ext"); + testExtension("/file.ext.", ""); + testExtension("/very-long-file.bruh", ".bruh"); + testExtension("/a.b.c", ".c"); + testExtension("/a.b.c/", ".c"); + + testExtension("/foo/bar/bam/", ""); + testExtension("/foo/bar/bam/.", ""); + testExtension("/foo/bar/bam/a.", ""); + testExtension("/foo/bar/bam/abc.", ""); + testExtension("/foo/bar/bam/.a", ""); + testExtension("/foo/bar/bam/.file", ""); + testExtension("/foo/bar/bam/.gitignore", ""); + testExtension("/foo/bar/bam/file.ext", ".ext"); + testExtension("/foo/bar/bam/file.ext.", ""); + testExtension("/foo/bar/bam/very-long-file.bruh", ".bruh"); + testExtension("/foo/bar/bam/a.b.c", ".c"); + testExtension("/foo/bar/bam/a.b.c/", ".c"); +} |
