Parse Path with clap and throw error on invalid path

I am currently using clap derive to parse my cli arguments in a Rust program. The code looks something like this:

    /// Path to the config file
    #[arg(
        short = 'c',
        long = "config",
        value_name = "CONFIG_FILE",
        default_value = "cof/system.conf"
    )]
    config_file: PathBuf,

I expected clap to through an error if it encountered an invalid path (maybe this was naive of me, since Paths can probably also be in an invalid state in Rust, i.e. the corresponding file does not exist). Any easy way to add this?

Typically I would avoid checking for the file's existence and just error out when opening the file causes an error (see TOCTOU, although I doubt there are any security concerns in this case). Even if the file exists, you may not have the permission to view/edit it etc.

In general, it's not commonly considered that a Path/PathBuf with no corresponding file is invalid.

In any case, you can use anything that implements FromStr and Clone as an argument in clap, so you can create your own wrapper for PathBuf that uses Path::exists in its FromStr implementation, something like:

#[derive(Clone)]
struct MyPath(PathBuf);

impl FromStr for MyPath {
    type Err = MyError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let path = PathBuf::from(s);
        if path.exists() {
            // return error
        }
        Ok(MyPath(path))
    }
}

But this feels a little suspect because a "valid" MyPath can turn "invalid" at any moment.

3 Likes

If a Path weren't allowed to exist unless it represented an existing file, then how would it be possible to create a file?

You should just attempt to open the file at the point it becomes necessary, and handle any errors you encounter.

4 Likes

You're right, my question turns out to be pretty dumb :slight_smile: Thanks

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.