Skip to content

Commit 94967d6

Browse files
committed
impl add_extension for PathBuf
Signed-off-by: tison <[email protected]>
1 parent 4e431fa commit 94967d6

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

library/std/src/path.rs

+74
Original file line numberDiff line numberDiff line change
@@ -1498,6 +1498,80 @@ impl PathBuf {
14981498
true
14991499
}
15001500

1501+
/// Updates [`self.extension`] to `Some(extension)` or to `None` if
1502+
/// `extension` is empty.
1503+
///
1504+
/// Returns `false` and does nothing if [`self.file_name`] is [`None`],
1505+
/// returns `true` and updates the extension otherwise.
1506+
///
1507+
/// If [`self.extension`] is [`None`], the extension is added; otherwise
1508+
/// it is replaced.
1509+
///
1510+
/// If `extension` is the empty string, [`self.extension`] will be [`None`]
1511+
/// afterwards, not `Some("")`.
1512+
///
1513+
/// # Caveats
1514+
///
1515+
/// The new `extension` may contain dots and will be used in its entirety,
1516+
/// but only the part after the final dot will be reflected in
1517+
/// [`self.extension`].
1518+
///
1519+
/// If the file stem contains internal dots and `extension` is empty, part
1520+
/// of the old file stem will be considered the new [`self.extension`].
1521+
///
1522+
/// See the examples below.
1523+
///
1524+
/// [`self.file_name`]: Path::file_name
1525+
/// [`self.extension`]: Path::extension
1526+
///
1527+
/// # Examples
1528+
///
1529+
/// ```
1530+
/// use std::path::{Path, PathBuf};
1531+
///
1532+
/// let mut p = PathBuf::from("/feel/the");
1533+
///
1534+
/// p.add_extension("formatted");
1535+
/// assert_eq!(Path::new("/feel/the.formatted"), p.as_path());
1536+
///
1537+
/// p.add_extension("dark.side");
1538+
/// assert_eq!(Path::new("/feel/the.formatted.dark.side"), p.as_path());
1539+
///
1540+
/// p.set_extension("cookie");
1541+
/// assert_eq!(Path::new("/feel/the.formatted.dark.cookie"), p.as_path());
1542+
///
1543+
/// p.set_extension("");
1544+
/// assert_eq!(Path::new("/feel/the.formatted.dark"), p.as_path());
1545+
/// p.set_extension("");
1546+
/// assert_eq!(Path::new("/feel/the.formatted"), p.as_path());
1547+
/// p.set_extension("");
1548+
/// assert_eq!(Path::new("/feel/the"), p.as_path());
1549+
/// p.set_extension("");
1550+
/// assert_eq!(Path::new("/feel/the"), p.as_path());
1551+
/// ```
1552+
#[stable(feature = "rust1", since = "1.0.0")]
1553+
pub fn add_extension<S: AsRef<OsStr>>(&mut self, extension: S) -> bool {
1554+
self._add_extension(extension.as_ref())
1555+
}
1556+
1557+
fn _add_extension(&mut self, extension: &OsStr) -> bool {
1558+
if self.file_stem().is_none() {
1559+
return false;
1560+
}
1561+
1562+
// add the new extension, if any
1563+
let v = self.as_mut_vec();
1564+
let new = extension.as_encoded_bytes();
1565+
if !new.is_empty() {
1566+
v.reserve_exact(new.len() + 1);
1567+
v.push(b'.');
1568+
v.extend_from_slice(new);
1569+
}
1570+
1571+
true
1572+
}
1573+
1574+
15011575
/// Yields a mutable reference to the underlying [`OsString`] instance.
15021576
///
15031577
/// # Examples

0 commit comments

Comments
 (0)