impl PathBuf::add_extension and Path::with_added_extension
Signed-off-by: tison <wander4096@gmail.com>
This commit is contained in:
parent
1cfd47fe0b
commit
57e76d4596
@ -1519,6 +1519,77 @@ fn _set_extension(&mut self, extension: &OsStr) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Append [`self.extension`] with `extension`.
|
||||
///
|
||||
/// Returns `false` and does nothing if [`self.file_name`] is [`None`],
|
||||
/// returns `true` and updates the extension otherwise.
|
||||
///
|
||||
/// If [`self.extension`] is [`None`], the extension is added; otherwise
|
||||
/// it is appended.
|
||||
///
|
||||
/// # Caveats
|
||||
///
|
||||
/// The appended `extension` may contain dots and will be used in its entirety,
|
||||
/// but only the part after the final dot will be reflected in
|
||||
/// [`self.extension`].
|
||||
///
|
||||
/// See the examples below.
|
||||
///
|
||||
/// [`self.file_name`]: Path::file_name
|
||||
/// [`self.extension`]: Path::extension
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(path_add_extension)]
|
||||
///
|
||||
/// use std::path::{Path, PathBuf};
|
||||
///
|
||||
/// let mut p = PathBuf::from("/feel/the");
|
||||
///
|
||||
/// p.add_extension("formatted");
|
||||
/// assert_eq!(Path::new("/feel/the.formatted"), p.as_path());
|
||||
///
|
||||
/// p.add_extension("dark.side");
|
||||
/// assert_eq!(Path::new("/feel/the.formatted.dark.side"), p.as_path());
|
||||
///
|
||||
/// p.set_extension("cookie");
|
||||
/// assert_eq!(Path::new("/feel/the.formatted.dark.cookie"), p.as_path());
|
||||
///
|
||||
/// p.set_extension("");
|
||||
/// assert_eq!(Path::new("/feel/the.formatted.dark"), p.as_path());
|
||||
///
|
||||
/// p.add_extension("");
|
||||
/// assert_eq!(Path::new("/feel/the.formatted.dark"), p.as_path());
|
||||
/// ```
|
||||
#[unstable(feature = "path_add_extension", issue = "127292")]
|
||||
pub fn add_extension<S: AsRef<OsStr>>(&mut self, extension: S) -> bool {
|
||||
self._add_extension(extension.as_ref())
|
||||
}
|
||||
|
||||
fn _add_extension(&mut self, extension: &OsStr) -> bool {
|
||||
let file_name = match self.file_name() {
|
||||
None => return false,
|
||||
Some(f) => f.as_encoded_bytes(),
|
||||
};
|
||||
|
||||
let new = extension;
|
||||
if !new.is_empty() {
|
||||
// truncate until right after the file name
|
||||
// this is necessary for trimming the trailing slash
|
||||
let end_file_name = file_name[file_name.len()..].as_ptr().addr();
|
||||
let start = self.inner.as_encoded_bytes().as_ptr().addr();
|
||||
self.inner.truncate(end_file_name.wrapping_sub(start));
|
||||
|
||||
// append the new extension
|
||||
self.inner.reserve_exact(new.len() + 1);
|
||||
self.inner.push(OsStr::new("."));
|
||||
self.inner.push(new);
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Yields a mutable reference to the underlying [`OsString`] instance.
|
||||
///
|
||||
/// # Examples
|
||||
@ -2656,6 +2727,32 @@ fn _with_extension(&self, extension: &OsStr) -> PathBuf {
|
||||
new_path
|
||||
}
|
||||
|
||||
/// Creates an owned [`PathBuf`] like `self` but with an extra extension.
|
||||
///
|
||||
/// See [`PathBuf::add_extension`] for more details.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(path_add_extension)]
|
||||
///
|
||||
/// use std::path::{Path, PathBuf};
|
||||
///
|
||||
/// let path = Path::new("foo.rs");
|
||||
/// assert_eq!(path.with_added_extension("txt"), PathBuf::from("foo.rs.txt"));
|
||||
///
|
||||
/// let path = Path::new("foo.tar.gz");
|
||||
/// assert_eq!(path.with_added_extension(""), PathBuf::from("foo.tar.gz"));
|
||||
/// assert_eq!(path.with_added_extension("xz"), PathBuf::from("foo.tar.gz.xz"));
|
||||
/// assert_eq!(path.with_added_extension("").with_added_extension("txt"), PathBuf::from("foo.tar.gz.txt"));
|
||||
/// ```
|
||||
#[unstable(feature = "path_add_extension", issue = "127292")]
|
||||
pub fn with_added_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
|
||||
let mut new_path = self.to_path_buf();
|
||||
new_path.add_extension(extension);
|
||||
new_path
|
||||
}
|
||||
|
||||
/// Produces an iterator over the [`Component`]s of the path.
|
||||
///
|
||||
/// When parsing the path, there is a small amount of normalization:
|
||||
|
Loading…
Reference in New Issue
Block a user