'Rust: Distinguish several cases in error handling of fs::remove_file

In Rust, I want to remove a file. The documentation tells me that fs::remove_file returns an error if the file is a directory, does not exist or the user lacks the permissions for the action.

Now, in my scenario, I would like to distinguish between those three cases. However, my debugger doesn't show me the type of the error and a println! results in simply printing the error message.

So, how could I distinguish between those cases?

use std::fs;

fn rem(path: &str) {
  let msg = match fs::remove_file(path) {
    Ok(()) => "is fine",
    Err(NotExist) => "does not exist", // TODO: Pattern
    Err(IsDir) => "is a directory", // TODO: Pattern
    Err(_) => "is not yours",
  };  
  println!("The file {}!", msg);
}

fn main() {
  rem("/tmp/this-file-hopefully-not-exists.xyz"); // print "not exist"
  rem("/tmp/this-is-a-directory"); // prints "is a directory"
  rem("/tmp/this-file-belongs-to-root.xyz"); // prints "is not yours"
}


Solution 1:[1]

std::fs::remove_file returns a std::io::Result<()>, which is just an alias for Result<(), std::io::Error>.

So you can match on this to extract the type of the error message. In particular, you're probably going to want to look at the .kind() of the error:

fn rem(path: &str) {
  use std::io::ErrorKind;

  let message = match std::fs::remove_file(path) {
    Ok(()) => "ok",
    Err(e) if e.kind() == ErrorKind::NotFound => "not found",
    Err(e) if e.kind() == ErrorKind::IsADirectory => "is a directory",
    Err(e) => "other",
  }
  println!("{message}");
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 cameron1024