| ... | @@ -1257,14 +1257,14 @@ fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []cons | ... | @@ -1257,14 +1257,14 @@ fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []cons |
| 1257 | /// Files that end with `.`, or that start with `.` and have no other `.` in their name, | 1257 | /// Files that end with `.`, or that start with `.` and have no other `.` in their name, |
| 1258 | /// are considered to have no extension. | 1258 | /// are considered to have no extension. |
| 1259 | /// Examples: | 1259 | /// Examples: |
| 1260 | /// - `"main.zig"` ⇒ `".zig"` | 1260 | /// - `"main.zig"` ⇒ `".zig"` |
| 1261 | /// - `"src/main.zig"` ⇒ `".zig"` | 1261 | /// - `"src/main.zig"` ⇒ `".zig"` |
| 1262 | /// - `".gitignore"` ⇒ `""` | 1262 | /// - `".gitignore"` ⇒ `""` |
| 1263 | /// - `".image.png"` ⇒ `".png"` | 1263 | /// - `".image.png"` ⇒ `".png"` |
| 1264 | /// - `"keep."` ⇒ `"."` | 1264 | /// - `"keep."` ⇒ `"."` |
| 1265 | /// - `"src.keep.me"` ⇒ `".me"` | 1265 | /// - `"src.keep.me"` ⇒ `".me"` |
| 1266 | /// - `"/src/keep.me"` ⇒ `".me"` | 1266 | /// - `"/src/keep.me"` ⇒ `".me"` |
| 1267 | /// - `"/src/keep.me/"` ⇒ `".me"` | 1267 | /// - `"/src/keep.me/"` ⇒ `".me"` |
| 1268 | /// The returned slice is guaranteed to have its pointer within the start and end | 1268 | /// The returned slice is guaranteed to have its pointer within the start and end |
| 1269 | /// pointer address range of `path`, even if it is length zero. | 1269 | /// pointer address range of `path`, even if it is length zero. |
| 1270 | pub fn extension(path: []const u8) []const u8 { | 1270 | pub fn extension(path: []const u8) []const u8 { |
| ... | @@ -1275,7 +1275,7 @@ pub fn extension(path: []const u8) []const u8 { | ... | @@ -1275,7 +1275,7 @@ pub fn extension(path: []const u8) []const u8 { |
| 1275 | } | 1275 | } |
| 1276 | | 1276 | |
| 1277 | fn testExtension(path: []const u8, expected: []const u8) !void { | 1277 | fn testExtension(path: []const u8, expected: []const u8) !void { |
| 1278 | try std.testing.expectEqualStrings(expected, extension(path)); | 1278 | try testing.expectEqualStrings(expected, extension(path)); |
| 1279 | } | 1279 | } |
| 1280 | | 1280 | |
| 1281 | test "extension" { | 1281 | test "extension" { |
| ... | @@ -1319,3 +1319,40 @@ test "extension" { | ... | @@ -1319,3 +1319,40 @@ test "extension" { |
| 1319 | try testExtension("/foo/bar/bam/a.b.c", ".c"); | 1319 | try testExtension("/foo/bar/bam/a.b.c", ".c"); |
| 1320 | try testExtension("/foo/bar/bam/a.b.c/", ".c"); | 1320 | try testExtension("/foo/bar/bam/a.b.c/", ".c"); |
| 1321 | } | 1321 | } |
| | 1322 | |
| | 1323 | /// Returns the last component of this path without its extension (if any): |
| | 1324 | /// - "hello/world/lib.tar.gz" ⇒ "lib.tar" |
| | 1325 | /// - "hello/world/lib.tar" ⇒ "lib" |
| | 1326 | /// - "hello/world/lib" ⇒ "lib" |
| | 1327 | pub fn stem(path: []const u8) []const u8 { |
| | 1328 | const filename = basename(path); |
| | 1329 | const index = mem.lastIndexOfScalar(u8, filename, '.') orelse return filename[0..]; |
| | 1330 | if (index == 0) return path; |
| | 1331 | return filename[0..index]; |
| | 1332 | } |
| | 1333 | |
| | 1334 | fn testStem(path: []const u8, expected: []const u8) !void { |
| | 1335 | try testing.expectEqualStrings(expected, stem(path)); |
| | 1336 | } |
| | 1337 | |
| | 1338 | test "stem" { |
| | 1339 | try testStem("hello/world/lib.tar.gz", "lib.tar"); |
| | 1340 | try testStem("hello/world/lib.tar", "lib"); |
| | 1341 | try testStem("hello/world/lib", "lib"); |
| | 1342 | try testStem("hello/lib/", "lib"); |
| | 1343 | try testStem("hello...", "hello.."); |
| | 1344 | try testStem("hello.", "hello"); |
| | 1345 | try testStem("/hello.", "hello"); |
| | 1346 | try testStem(".gitignore", ".gitignore"); |
| | 1347 | try testStem(".image.png", ".image"); |
| | 1348 | try testStem("file.ext", "file"); |
| | 1349 | try testStem("file.ext.", "file.ext"); |
| | 1350 | try testStem("a.b.c", "a.b"); |
| | 1351 | try testStem("a.b.c/", "a.b"); |
| | 1352 | try testStem(".a", ".a"); |
| | 1353 | try testStem("///", ""); |
| | 1354 | try testStem("..", "."); |
| | 1355 | try testStem(".", "."); |
| | 1356 | try testStem(" ", " "); |
| | 1357 | try testStem("", ""); |
| | 1358 | } |