@@ -1498,6 +1498,76 @@ impl PathBuf {
1498
1498
true
1499
1499
}
1500
1500
1501
+ /// Append [`self.extension`] with `extension`.
1502
+ ///
1503
+ /// Returns `false` and does nothing if [`self.file_name`] is [`None`],
1504
+ /// returns `true` and updates the extension otherwise.
1505
+ ///
1506
+ /// If [`self.extension`] is [`None`], the extension is added; otherwise
1507
+ /// it is appended.
1508
+ ///
1509
+ /// # Caveats
1510
+ ///
1511
+ /// The appended `extension` may contain dots and will be used in its entirety,
1512
+ /// but only the part after the final dot will be reflected in
1513
+ /// [`self.extension`].
1514
+ ///
1515
+ /// See the examples below.
1516
+ ///
1517
+ /// [`self.file_name`]: Path::file_name
1518
+ /// [`self.extension`]: Path::extension
1519
+ ///
1520
+ /// # Examples
1521
+ ///
1522
+ /// ```
1523
+ /// use std::path::{Path, PathBuf};
1524
+ ///
1525
+ /// let mut p = PathBuf::from("/feel/the");
1526
+ ///
1527
+ /// p.add_extension("formatted");
1528
+ /// assert_eq!(Path::new("/feel/the.formatted"), p.as_path());
1529
+ ///
1530
+ /// p.add_extension("dark.side");
1531
+ /// assert_eq!(Path::new("/feel/the.formatted.dark.side"), p.as_path());
1532
+ ///
1533
+ /// p.set_extension("cookie");
1534
+ /// assert_eq!(Path::new("/feel/the.formatted.dark.cookie"), p.as_path());
1535
+ ///
1536
+ /// p.set_extension("");
1537
+ /// assert_eq!(Path::new("/feel/the.formatted.dark"), p.as_path());
1538
+ ///
1539
+ /// p.add_extension("");
1540
+ /// assert_eq!(Path::new("/feel/the.formatted.dark"), p.as_path());
1541
+ /// ```
1542
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1543
+ pub fn add_extension < S : AsRef < OsStr > > ( & mut self , extension : S ) -> bool {
1544
+ self . _add_extension ( extension. as_ref ( ) )
1545
+ }
1546
+
1547
+ fn _add_extension ( & mut self , extension : & OsStr ) -> bool {
1548
+ let file_name = match self . file_name ( ) {
1549
+ None => return false ,
1550
+ Some ( f) => f. as_encoded_bytes ( ) ,
1551
+ } ;
1552
+
1553
+ let new = extension. as_encoded_bytes ( ) ;
1554
+ if !new. is_empty ( ) {
1555
+ // truncate until right after the file name
1556
+ // this is necessary for trimming the trailing slash
1557
+ let end_file_name = file_name[ file_name. len ( ) ..] . as_ptr ( ) . addr ( ) ;
1558
+ let start = self . inner . as_encoded_bytes ( ) . as_ptr ( ) . addr ( ) ;
1559
+ let v = self . as_mut_vec ( ) ;
1560
+ v. truncate ( end_file_name. wrapping_sub ( start) ) ;
1561
+
1562
+ // append the new extension
1563
+ v. reserve_exact ( new. len ( ) + 1 ) ;
1564
+ v. push ( b'.' ) ;
1565
+ v. extend_from_slice ( new) ;
1566
+ }
1567
+
1568
+ true
1569
+ }
1570
+
1501
1571
/// Yields a mutable reference to the underlying [`OsString`] instance.
1502
1572
///
1503
1573
/// # Examples
0 commit comments