The PathBuf struct has a method called set_extension. One would thing that it is the tool that we always need to use to, well, set the extension of a file.
Unfortunately it has some caveats. Specifically that if the file has a dot in it, the set_extension
will consider the part after the last dot as the current extension and it will replace it with the new one.
So when I was working on the MSRV report of the Rust Digger this created a mess.
It took me some time to understand the problem and then went for the axe, or at least the format!
macro that you can also see in the examples:
examples/set-file-extension/src/main.rs
fn main() {
let mut path = std::path::PathBuf::from("hello");
println!("{:?}", path); // "hello"
// adds an extension
path.set_extension("txt");
println!("{:?}", path); // "hello.txt"
// replaces an extension
path.set_extension("html");
println!("{:?}", path); // "hello.html"
// If we have a file that has a . in the name, for example
let mut path = std::path::PathBuf::from("hello.0");
println!("{:?}", path); // "hello.0"
// and we would like to add an extension, this will not do what we
// want as this will replace the 0 by the html
path.set_extension("html");
println!("{:?}", path); // "hello.html"
let path = std::path::PathBuf::from("hello.0");
println!("{:?}", path); // "hello.0"
println!("{}", format!("{}.html", path.display())); // hello.0.html
let path = std::path::PathBuf::from(format!("{}.html", path.display()));
println!("{:?}", path); // "hello.0.html"
}