1
Fork 0

Auto merge of #85166 - mbhall88:file-prefix, r=dtolnay

add file_prefix method to std::path

This is an initial implementation of `std::path::Path::file_prefix`. It is effectively a "left" variant of the existing [`file_stem`](https://doc.rust-lang.org/std/path/struct.Path.html#method.file_stem) method. An illustration of the difference is

```rust
use std::path::Path;

let path = Path::new("foo.tar.gz");
assert_eq!(path.file_stem(), Some("foo.tar"));
assert_eq!(path.file_prefix(), Some("foo"));
```

In my own development, I generally find I almost always want the prefix, rather than the stem, so I thought it might be best to suggest it's addition to libstd.

Of course, as this is my first contribution, I expect there is probably more work that needs to be done. Additionally, if the libstd team feel this isn't appropriate then so be it.

There has been some [discussion about this on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/file_lstem/near/238076313) and a user there suggested I open a PR to see whether someone in the libstd team thinks it is worth pursuing.
This commit is contained in:
bors 2021-08-22 05:19:48 +00:00
commit 2ad56d5c90
2 changed files with 372 additions and 90 deletions

View file

@ -315,7 +315,7 @@ fn has_physical_root(s: &[u8], prefix: Option<Prefix<'_>>) -> bool {
}
// basic workhorse for splitting stem and extension
fn split_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
if os_str_as_u8_slice(file) == b".." {
return (Some(file), None);
}
@ -334,6 +334,25 @@ fn split_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
}
}
fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
let slice = os_str_as_u8_slice(file);
if slice == b".." {
return (file, None);
}
// The unsafety here stems from converting between &OsStr and &[u8]
// and back. This is safe to do because (1) we only look at ASCII
// contents of the encoding and (2) new &OsStr values are produced
// only from ASCII-bounded slices of existing &OsStr values.
let i = match slice[1..].iter().position(|b| *b == b'.') {
Some(i) => i + 1,
None => return (file, None),
};
let before = &slice[..i];
let after = &slice[i + 1..];
unsafe { (u8_slice_as_os_str(before), Some(u8_slice_as_os_str(after))) }
}
////////////////////////////////////////////////////////////////////////////////
// The core iterators
////////////////////////////////////////////////////////////////////////////////
@ -2213,9 +2232,49 @@ impl Path {
/// assert_eq!("foo", Path::new("foo.rs").file_stem().unwrap());
/// assert_eq!("foo.tar", Path::new("foo.tar.gz").file_stem().unwrap());
/// ```
///
/// # See Also
/// This method is similar to [`Path::file_prefix`], which extracts the portion of the file name
/// before the *first* `.`
///
/// [`Path::file_prefix`]: Path::file_prefix
///
#[stable(feature = "rust1", since = "1.0.0")]
pub fn file_stem(&self) -> Option<&OsStr> {
self.file_name().map(split_file_at_dot).and_then(|(before, after)| before.or(after))
self.file_name().map(rsplit_file_at_dot).and_then(|(before, after)| before.or(after))
}
/// Extracts the prefix of [`self.file_name`].
///
/// The prefix is:
///
/// * [`None`], if there is no file name;
/// * The entire file name if there is no embedded `.`;
/// * The portion of the file name before the first non-beginning `.`;
/// * The entire file name if the file name begins with `.` and has no other `.`s within;
/// * The portion of the file name before the second `.` if the file name begins with `.`
///
/// [`self.file_name`]: Path::file_name
///
/// # Examples
///
/// ```
/// # #![feature(path_file_prefix)]
/// use std::path::Path;
///
/// assert_eq!("foo", Path::new("foo.rs").file_prefix().unwrap());
/// assert_eq!("foo", Path::new("foo.tar.gz").file_prefix().unwrap());
/// ```
///
/// # See Also
/// This method is similar to [`Path::file_stem`], which extracts the portion of the file name
/// before the *last* `.`
///
/// [`Path::file_stem`]: Path::file_stem
///
#[unstable(feature = "path_file_prefix", issue = "86319")]
pub fn file_prefix(&self) -> Option<&OsStr> {
self.file_name().map(split_file_at_dot).and_then(|(before, _after)| Some(before))
}
/// Extracts the extension of [`self.file_name`], if possible.
@ -2239,7 +2298,7 @@ impl Path {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn extension(&self) -> Option<&OsStr> {
self.file_name().map(split_file_at_dot).and_then(|(before, after)| before.and(after))
self.file_name().map(rsplit_file_at_dot).and_then(|(before, after)| before.and(after))
}
/// Creates an owned [`PathBuf`] with `path` adjoined to `self`.

View file

@ -75,15 +75,33 @@ macro_rules! t(
}
);
($path:expr, file_prefix: $file_prefix:expr, extension: $extension:expr) => (
{
let path = Path::new($path);
let prefix = path.file_prefix().map(|p| p.to_str().unwrap());
let exp_prefix: Option<&str> = $file_prefix;
assert!(prefix == exp_prefix, "file_prefix: Expected {:?}, found {:?}",
exp_prefix, prefix);
let ext = path.extension().map(|p| p.to_str().unwrap());
let exp_ext: Option<&str> = $extension;
assert!(ext == exp_ext, "extension: Expected {:?}, found {:?}",
exp_ext, ext);
}
);
($path:expr, iter: $iter:expr,
has_root: $has_root:expr, is_absolute: $is_absolute:expr,
parent: $parent:expr, file_name: $file:expr,
file_stem: $file_stem:expr, extension: $extension:expr) => (
file_stem: $file_stem:expr, extension: $extension:expr,
file_prefix: $file_prefix:expr) => (
{
t!($path, iter: $iter);
t!($path, has_root: $has_root, is_absolute: $is_absolute);
t!($path, parent: $parent, file_name: $file);
t!($path, file_stem: $file_stem, extension: $extension);
t!($path, file_prefix: $file_prefix, extension: $extension);
}
);
);
@ -118,7 +136,8 @@ pub fn test_decompositions_unix() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("foo",
@ -128,7 +147,8 @@ pub fn test_decompositions_unix() {
parent: Some(""),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("/",
@ -138,7 +158,8 @@ pub fn test_decompositions_unix() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("/foo",
@ -148,7 +169,8 @@ pub fn test_decompositions_unix() {
parent: Some("/"),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("foo/",
@ -158,7 +180,8 @@ pub fn test_decompositions_unix() {
parent: Some(""),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("/foo/",
@ -168,7 +191,8 @@ pub fn test_decompositions_unix() {
parent: Some("/"),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("foo/bar",
@ -178,7 +202,8 @@ pub fn test_decompositions_unix() {
parent: Some("foo"),
file_name: Some("bar"),
file_stem: Some("bar"),
extension: None
extension: None,
file_prefix: Some("bar")
);
t!("/foo/bar",
@ -188,7 +213,8 @@ pub fn test_decompositions_unix() {
parent: Some("/foo"),
file_name: Some("bar"),
file_stem: Some("bar"),
extension: None
extension: None,
file_prefix: Some("bar")
);
t!("///foo///",
@ -198,7 +224,8 @@ pub fn test_decompositions_unix() {
parent: Some("/"),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("///foo///bar",
@ -208,7 +235,8 @@ pub fn test_decompositions_unix() {
parent: Some("///foo"),
file_name: Some("bar"),
file_stem: Some("bar"),
extension: None
extension: None,
file_prefix: Some("bar")
);
t!("./.",
@ -218,7 +246,8 @@ pub fn test_decompositions_unix() {
parent: Some(""),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("/..",
@ -228,7 +257,8 @@ pub fn test_decompositions_unix() {
parent: Some("/"),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("../",
@ -238,7 +268,8 @@ pub fn test_decompositions_unix() {
parent: Some(""),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("foo/.",
@ -248,7 +279,8 @@ pub fn test_decompositions_unix() {
parent: Some(""),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("foo/..",
@ -258,7 +290,8 @@ pub fn test_decompositions_unix() {
parent: Some("foo"),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("foo/./",
@ -268,7 +301,8 @@ pub fn test_decompositions_unix() {
parent: Some(""),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("foo/./bar",
@ -278,7 +312,8 @@ pub fn test_decompositions_unix() {
parent: Some("foo"),
file_name: Some("bar"),
file_stem: Some("bar"),
extension: None
extension: None,
file_prefix: Some("bar")
);
t!("foo/../",
@ -288,7 +323,8 @@ pub fn test_decompositions_unix() {
parent: Some("foo"),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("foo/../bar",
@ -298,7 +334,8 @@ pub fn test_decompositions_unix() {
parent: Some("foo/.."),
file_name: Some("bar"),
file_stem: Some("bar"),
extension: None
extension: None,
file_prefix: Some("bar")
);
t!("./a",
@ -308,7 +345,8 @@ pub fn test_decompositions_unix() {
parent: Some("."),
file_name: Some("a"),
file_stem: Some("a"),
extension: None
extension: None,
file_prefix: Some("a")
);
t!(".",
@ -318,7 +356,8 @@ pub fn test_decompositions_unix() {
parent: Some(""),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("./",
@ -328,7 +367,8 @@ pub fn test_decompositions_unix() {
parent: Some(""),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("a/b",
@ -338,7 +378,8 @@ pub fn test_decompositions_unix() {
parent: Some("a"),
file_name: Some("b"),
file_stem: Some("b"),
extension: None
extension: None,
file_prefix: Some("b")
);
t!("a//b",
@ -348,7 +389,8 @@ pub fn test_decompositions_unix() {
parent: Some("a"),
file_name: Some("b"),
file_stem: Some("b"),
extension: None
extension: None,
file_prefix: Some("b")
);
t!("a/./b",
@ -358,7 +400,8 @@ pub fn test_decompositions_unix() {
parent: Some("a"),
file_name: Some("b"),
file_stem: Some("b"),
extension: None
extension: None,
file_prefix: Some("b")
);
t!("a/b/c",
@ -368,7 +411,8 @@ pub fn test_decompositions_unix() {
parent: Some("a/b"),
file_name: Some("c"),
file_stem: Some("c"),
extension: None
extension: None,
file_prefix: Some("c")
);
t!(".foo",
@ -378,7 +422,41 @@ pub fn test_decompositions_unix() {
parent: Some(""),
file_name: Some(".foo"),
file_stem: Some(".foo"),
extension: None
extension: None,
file_prefix: Some(".foo")
);
t!("a/.foo",
iter: ["a", ".foo"],
has_root: false,
is_absolute: false,
parent: Some("a"),
file_name: Some(".foo"),
file_stem: Some(".foo"),
extension: None,
file_prefix: Some(".foo")
);
t!("a/.rustfmt.toml",
iter: ["a", ".rustfmt.toml"],
has_root: false,
is_absolute: false,
parent: Some("a"),
file_name: Some(".rustfmt.toml"),
file_stem: Some(".rustfmt"),
extension: Some("toml"),
file_prefix: Some(".rustfmt")
);
t!("a/.x.y.z",
iter: ["a", ".x.y.z"],
has_root: false,
is_absolute: false,
parent: Some("a"),
file_name: Some(".x.y.z"),
file_stem: Some(".x.y"),
extension: Some("z"),
file_prefix: Some(".x")
);
}
@ -392,7 +470,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("foo",
@ -402,7 +481,8 @@ pub fn test_decompositions_windows() {
parent: Some(""),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("/",
@ -412,7 +492,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("\\",
@ -422,7 +503,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("c:",
@ -432,7 +514,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("c:\\",
@ -442,7 +525,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("c:/",
@ -452,7 +536,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("/foo",
@ -462,7 +547,8 @@ pub fn test_decompositions_windows() {
parent: Some("/"),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("foo/",
@ -472,7 +558,8 @@ pub fn test_decompositions_windows() {
parent: Some(""),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("/foo/",
@ -482,7 +569,8 @@ pub fn test_decompositions_windows() {
parent: Some("/"),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("foo/bar",
@ -492,7 +580,8 @@ pub fn test_decompositions_windows() {
parent: Some("foo"),
file_name: Some("bar"),
file_stem: Some("bar"),
extension: None
extension: None,
file_prefix: Some("bar")
);
t!("/foo/bar",
@ -502,7 +591,8 @@ pub fn test_decompositions_windows() {
parent: Some("/foo"),
file_name: Some("bar"),
file_stem: Some("bar"),
extension: None
extension: None,
file_prefix: Some("bar")
);
t!("///foo///",
@ -512,7 +602,8 @@ pub fn test_decompositions_windows() {
parent: Some("/"),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("///foo///bar",
@ -522,7 +613,8 @@ pub fn test_decompositions_windows() {
parent: Some("///foo"),
file_name: Some("bar"),
file_stem: Some("bar"),
extension: None
extension: None,
file_prefix: Some("bar")
);
t!("./.",
@ -532,7 +624,8 @@ pub fn test_decompositions_windows() {
parent: Some(""),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("/..",
@ -542,7 +635,8 @@ pub fn test_decompositions_windows() {
parent: Some("/"),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("../",
@ -552,7 +646,8 @@ pub fn test_decompositions_windows() {
parent: Some(""),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("foo/.",
@ -562,7 +657,8 @@ pub fn test_decompositions_windows() {
parent: Some(""),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("foo/..",
@ -572,7 +668,8 @@ pub fn test_decompositions_windows() {
parent: Some("foo"),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("foo/./",
@ -582,7 +679,8 @@ pub fn test_decompositions_windows() {
parent: Some(""),
file_name: Some("foo"),
file_stem: Some("foo"),
extension: None
extension: None,
file_prefix: Some("foo")
);
t!("foo/./bar",
@ -592,7 +690,8 @@ pub fn test_decompositions_windows() {
parent: Some("foo"),
file_name: Some("bar"),
file_stem: Some("bar"),
extension: None
extension: None,
file_prefix: Some("bar")
);
t!("foo/../",
@ -602,7 +701,8 @@ pub fn test_decompositions_windows() {
parent: Some("foo"),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("foo/../bar",
@ -612,7 +712,8 @@ pub fn test_decompositions_windows() {
parent: Some("foo/.."),
file_name: Some("bar"),
file_stem: Some("bar"),
extension: None
extension: None,
file_prefix: Some("bar")
);
t!("./a",
@ -622,7 +723,8 @@ pub fn test_decompositions_windows() {
parent: Some("."),
file_name: Some("a"),
file_stem: Some("a"),
extension: None
extension: None,
file_prefix: Some("a")
);
t!(".",
@ -632,7 +734,8 @@ pub fn test_decompositions_windows() {
parent: Some(""),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("./",
@ -642,7 +745,8 @@ pub fn test_decompositions_windows() {
parent: Some(""),
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("a/b",
@ -652,7 +756,8 @@ pub fn test_decompositions_windows() {
parent: Some("a"),
file_name: Some("b"),
file_stem: Some("b"),
extension: None
extension: None,
file_prefix: Some("b")
);
t!("a//b",
@ -662,7 +767,8 @@ pub fn test_decompositions_windows() {
parent: Some("a"),
file_name: Some("b"),
file_stem: Some("b"),
extension: None
extension: None,
file_prefix: Some("b")
);
t!("a/./b",
@ -672,7 +778,8 @@ pub fn test_decompositions_windows() {
parent: Some("a"),
file_name: Some("b"),
file_stem: Some("b"),
extension: None
extension: None,
file_prefix: Some("b")
);
t!("a/b/c",
@ -682,7 +789,9 @@ pub fn test_decompositions_windows() {
parent: Some("a/b"),
file_name: Some("c"),
file_stem: Some("c"),
extension: None);
extension: None,
file_prefix: Some("c")
);
t!("a\\b\\c",
iter: ["a", "b", "c"],
@ -691,7 +800,8 @@ pub fn test_decompositions_windows() {
parent: Some("a\\b"),
file_name: Some("c"),
file_stem: Some("c"),
extension: None
extension: None,
file_prefix: Some("c")
);
t!("\\a",
@ -701,7 +811,8 @@ pub fn test_decompositions_windows() {
parent: Some("\\"),
file_name: Some("a"),
file_stem: Some("a"),
extension: None
extension: None,
file_prefix: Some("a")
);
t!("c:\\foo.txt",
@ -711,7 +822,8 @@ pub fn test_decompositions_windows() {
parent: Some("c:\\"),
file_name: Some("foo.txt"),
file_stem: Some("foo"),
extension: Some("txt")
extension: Some("txt"),
file_prefix: Some("foo")
);
t!("\\\\server\\share\\foo.txt",
@ -721,7 +833,8 @@ pub fn test_decompositions_windows() {
parent: Some("\\\\server\\share\\"),
file_name: Some("foo.txt"),
file_stem: Some("foo"),
extension: Some("txt")
extension: Some("txt"),
file_prefix: Some("foo")
);
t!("\\\\server\\share",
@ -731,7 +844,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("\\\\server",
@ -741,7 +855,8 @@ pub fn test_decompositions_windows() {
parent: Some("\\"),
file_name: Some("server"),
file_stem: Some("server"),
extension: None
extension: None,
file_prefix: Some("server")
);
t!("\\\\?\\bar\\foo.txt",
@ -751,7 +866,8 @@ pub fn test_decompositions_windows() {
parent: Some("\\\\?\\bar\\"),
file_name: Some("foo.txt"),
file_stem: Some("foo"),
extension: Some("txt")
extension: Some("txt"),
file_prefix: Some("foo")
);
t!("\\\\?\\bar",
@ -761,7 +877,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("\\\\?\\",
@ -771,7 +888,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("\\\\?\\UNC\\server\\share\\foo.txt",
@ -781,7 +899,8 @@ pub fn test_decompositions_windows() {
parent: Some("\\\\?\\UNC\\server\\share\\"),
file_name: Some("foo.txt"),
file_stem: Some("foo"),
extension: Some("txt")
extension: Some("txt"),
file_prefix: Some("foo")
);
t!("\\\\?\\UNC\\server",
@ -791,7 +910,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("\\\\?\\UNC\\",
@ -801,7 +921,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("\\\\?\\C:\\foo.txt",
@ -811,7 +932,8 @@ pub fn test_decompositions_windows() {
parent: Some("\\\\?\\C:\\"),
file_name: Some("foo.txt"),
file_stem: Some("foo"),
extension: Some("txt")
extension: Some("txt"),
file_prefix: Some("foo")
);
t!("\\\\?\\C:\\",
@ -821,7 +943,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("\\\\?\\C:",
@ -831,7 +954,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("\\\\?\\foo/bar",
@ -841,7 +965,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("\\\\?\\C:/foo",
@ -851,7 +976,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("\\\\.\\foo\\bar",
@ -861,7 +987,8 @@ pub fn test_decompositions_windows() {
parent: Some("\\\\.\\foo\\"),
file_name: Some("bar"),
file_stem: Some("bar"),
extension: None
extension: None,
file_prefix: Some("bar")
);
t!("\\\\.\\foo",
@ -871,7 +998,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("\\\\.\\foo/bar",
@ -881,7 +1009,8 @@ pub fn test_decompositions_windows() {
parent: Some("\\\\.\\foo/"),
file_name: Some("bar"),
file_stem: Some("bar"),
extension: None
extension: None,
file_prefix: Some("bar")
);
t!("\\\\.\\foo\\bar/baz",
@ -891,7 +1020,8 @@ pub fn test_decompositions_windows() {
parent: Some("\\\\.\\foo\\bar"),
file_name: Some("baz"),
file_stem: Some("baz"),
extension: None
extension: None,
file_prefix: Some("baz")
);
t!("\\\\.\\",
@ -901,7 +1031,8 @@ pub fn test_decompositions_windows() {
parent: None,
file_name: None,
file_stem: None,
extension: None
extension: None,
file_prefix: None
);
t!("\\\\?\\a\\b\\",
@ -911,7 +1042,52 @@ pub fn test_decompositions_windows() {
parent: Some("\\\\?\\a\\"),
file_name: Some("b"),
file_stem: Some("b"),
extension: None
extension: None,
file_prefix: Some("b")
);
t!("\\\\?\\C:\\foo.txt.zip",
iter: ["\\\\?\\C:", "\\", "foo.txt.zip"],
has_root: true,
is_absolute: true,
parent: Some("\\\\?\\C:\\"),
file_name: Some("foo.txt.zip"),
file_stem: Some("foo.txt"),
extension: Some("zip"),
file_prefix: Some("foo")
);
t!("\\\\?\\C:\\.foo.txt.zip",
iter: ["\\\\?\\C:", "\\", ".foo.txt.zip"],
has_root: true,
is_absolute: true,
parent: Some("\\\\?\\C:\\"),
file_name: Some(".foo.txt.zip"),
file_stem: Some(".foo.txt"),
extension: Some("zip"),
file_prefix: Some(".foo")
);
t!("\\\\?\\C:\\.foo",
iter: ["\\\\?\\C:", "\\", ".foo"],
has_root: true,
is_absolute: true,
parent: Some("\\\\?\\C:\\"),
file_name: Some(".foo"),
file_stem: Some(".foo"),
extension: None,
file_prefix: Some(".foo")
);
t!("a/.x.y.z",
iter: ["a", ".x.y.z"],
has_root: false,
is_absolute: false,
parent: Some("a"),
file_name: Some(".x.y.z"),
file_stem: Some(".x.y"),
extension: Some("z"),
file_prefix: Some(".x")
);
}
@ -951,9 +1127,56 @@ pub fn test_stem_ext() {
t!("..", file_stem: None, extension: None);
t!(".x.y.z", file_stem: Some(".x.y"), extension: Some("z"));
t!("..x.y.z", file_stem: Some("..x.y"), extension: Some("z"));
t!("", file_stem: None, extension: None);
}
#[test]
pub fn test_prefix_ext() {
t!("foo",
file_prefix: Some("foo"),
extension: None
);
t!("foo.",
file_prefix: Some("foo"),
extension: Some("")
);
t!(".foo",
file_prefix: Some(".foo"),
extension: None
);
t!("foo.txt",
file_prefix: Some("foo"),
extension: Some("txt")
);
t!("foo.bar.txt",
file_prefix: Some("foo"),
extension: Some("txt")
);
t!("foo.bar.",
file_prefix: Some("foo"),
extension: Some("")
);
t!(".", file_prefix: None, extension: None);
t!("..", file_prefix: None, extension: None);
t!(".x.y.z", file_prefix: Some(".x"), extension: Some("z"));
t!("..x.y.z", file_prefix: Some("."), extension: Some("z"));
t!("", file_prefix: None, extension: None);
}
#[test]
pub fn test_push() {
macro_rules! tp (