Skip to content

Commit

Permalink
impl add_extension for PathBuf
Browse files Browse the repository at this point in the history
Signed-off-by: tison <wander4096@gmail.com>
  • Loading branch information
tisonkun committed Apr 7, 2024
1 parent 4e431fa commit 94967d6
Showing 1 changed file with 74 additions and 0 deletions.
74 changes: 74 additions & 0 deletions library/std/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1498,6 +1498,80 @@ impl PathBuf {
true
}

/// Updates [`self.extension`] to `Some(extension)` or to `None` if
/// `extension` is empty.
///
/// 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 replaced.
///
/// If `extension` is the empty string, [`self.extension`] will be [`None`]
/// afterwards, not `Some("")`.
///
/// # Caveats
///
/// The new `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`].
///
/// If the file stem contains internal dots and `extension` is empty, part
/// of the old file stem will be considered the new [`self.extension`].
///
/// See the examples below.
///
/// [`self.file_name`]: Path::file_name
/// [`self.extension`]: Path::extension
///
/// # Examples
///
/// ```
/// 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.set_extension("");
/// assert_eq!(Path::new("/feel/the.formatted"), p.as_path());
/// p.set_extension("");
/// assert_eq!(Path::new("/feel/the"), p.as_path());
/// p.set_extension("");
/// assert_eq!(Path::new("/feel/the"), p.as_path());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
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 {
if self.file_stem().is_none() {
return false;
}

// add the new extension, if any
let v = self.as_mut_vec();
let new = extension.as_encoded_bytes();
if !new.is_empty() {
v.reserve_exact(new.len() + 1);
v.push(b'.');
v.extend_from_slice(new);
}

true
}


/// Yields a mutable reference to the underlying [`OsString`] instance.
///
/// # Examples
Expand Down

0 comments on commit 94967d6

Please sign in to comment.