PathBuf equivalent to String.is_empty()?

#1

This works:

let mut p = PathBuf::new("");

Clearly p isn’t really a path at this point since it is empty. But there isn’t a PathBuf.is_empty() method, so what is the appropriate (and cheapest) way to test for this case?

What I’m thinking of doing is adding a new trait:

pub trait PathBufExt {
    fn is_empty(&self) -> bool;
}

impl PathBufExt for PathBuf {
    fn is_empty(&self) -> bool {
        // what is best here?
        self.as_os_str().is_empty()
    }
}
1 Like
#2

My guess is that there probably should be an is_empty method on paths, but in lieu of that, your approach sounds fine, sure. path.as_os_str().is_empty() is how I would implement it.

#3

I don’t know any platforms that allow “” as a valid path, but it feels dangerous to assume that it’s always going to be invalid. Apparently it was equivalent to the current directory on some very old systems. Why do you want to treat empty paths specially?

#4

Thanks, I’ll stick with .as_os_str().is_empty() then.

The reason I need empty paths is that I have structs which have PathBuf fields which may be empty. Uh oh, so now I guess you’ll say they should be Option<PathBuf>… I’ll rethink this!

I still think Path::is_empty() ought to be present given that you can write Path::new("") or PathBuf::new().as_path().

Incidentally, I sometimes create a path like this: Path::new("$PATH/file.ext") and then later on I want to say path.replace("$PATH", &path). I’ve done this, but only by using to_string_lossy().

#5

The reason I need empty paths is that I have struct s which have PathBuf fields which may be empty. Uh oh , so now I guess you’ll say they should be Option<PathBuf> … I’ll rethink this!

You almost certainly want Option<PathBuf>. They’re both the exact same size, and with the Option, you won’t ever accidentally forget to check whether it’s empty.

1 Like
#6

Path::join seems to treat it the same as “.”.

1 Like
#7

For URIs, "" is a valid relative URI (URI-Reference) with a different behavior than ".":

Assuming the path of the base URI is "/a/b/c.ext":

  • "." resolves to "/a/b/"
  • "" resolves to "/a/b/c.ext"

i.e. "" is exactly the base URI and "." is the directory of the base URI. If the base URI ends with a /, they are the same.

Path::join always seems to treat the first part as directory (implicitly assuming a trailing /), so the behavior would be somewhat consistent.