@@ -1498,6 +1498,76 @@ impl PathBuf {
14981498        true 
14991499    } 
15001500
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+ 
15011571    /// Yields a mutable reference to the underlying [`OsString`] instance. 
15021572/// 
15031573/// # Examples 
0 commit comments