Set the file extension in Rust

PathBuf set_extension

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"
}

Related Pages

Files - dealing with files in Rust

Author

Gabor Szabo (szabgab)

Gabor Szabo, the author of the Rust Maven web site maintains several Open source projects in Rust and while he still feels he has tons of new things to learn about Rust he already offers training courses in Rust and still teaches Python, Perl, git, GitHub, GitLab, CI, and testing.

Gabor Szabo