-
Notifications
You must be signed in to change notification settings - Fork 13.9k
add file_prefix method to std::path #85166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
3e2206a
b1d84f7
7465192
a889529
fcb1ebf
1e759be
51cf318
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
|
|
@@ -2156,9 +2175,51 @@ 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)| if before.is_empty() { after } else { Some(before) }) | ||
|
||
| } | ||
|
|
||
| /// Extracts the extension of [`self.file_name`], if possible. | ||
|
|
@@ -2182,7 +2243,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`. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.