1
Fork 0

Prevent unnecessary allocation in PathBuf::set_extension.

It was allocating a new OsString that was immediately dropped after
using it with set_file_name. Now it directly changes the extension in
the original buffer, without touching the rest of the file name or
allocating a temporary string.
This commit is contained in:
Mara Bos 2019-10-23 21:00:04 +02:00
parent 4a8c5b20c7
commit 18ae175d60

View file

@ -1363,20 +1363,24 @@ impl PathBuf {
} }
fn _set_extension(&mut self, extension: &OsStr) -> bool { fn _set_extension(&mut self, extension: &OsStr) -> bool {
if self.file_name().is_none() { let file_stem = match self.file_stem() {
return false; None => return false,
} Some(f) => os_str_as_u8_slice(f),
let mut stem = match self.file_stem() {
Some(stem) => stem.to_os_string(),
None => OsString::new(),
}; };
if !os_str_as_u8_slice(extension).is_empty() { // truncate until right after the file stem
stem.push("."); let end_file_stem = file_stem[file_stem.len()..].as_ptr() as usize;
stem.push(extension); let start = os_str_as_u8_slice(&self.inner).as_ptr() as usize;
let v = self.as_mut_vec();
v.truncate(end_file_stem.wrapping_sub(start));
// add the new extension, if any
let new = os_str_as_u8_slice(extension);
if !new.is_empty() {
v.reserve_exact(new.len() + 1);
v.push(b'.');
v.extend_from_slice(new);
} }
self.set_file_name(&stem);
true true
} }