Why does Path::extension not consider slashes?

I'm using Path::extension on shared drives with paths like \\mydomain.com\one\two\three. Because it just finds the last . and yields what comes after, it returns com\one\two\three as the extension because three is a file without an extension.

Shouldn't it first find the last path segment and apply the same logic to that alone?

Yes it should and it actually does! But the issue is what it considers a path separator. On Windows the function thinks both \ and / are path separators. But on *nix it only thinks / is a path separator.

The Rust playground runs on Linux so you can see the difference here: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3086b684f74927ab21870d944e4acf24


Output:

[src/main.rs:4] Path::new(r"//mydomain.com/one/two/three").extension() = None
[src/main.rs:8] Path::new(r"\\mydomain.com\one\two\three").extension() = Some(
    "com\\one\\two\\three",
)

Interesting... I'm processing data which includes Windows paths, but the processing is being done on a Linux machine. Is there a way to have it handle this the way it would on Windows?

Sorry, I don't think so. The behaviour of path is decided at compile time based on the target platform. There might be a library on crates.io that can help but I'm not familiar with any of them.

You could do this in two steps:

  1. Convert Windows-like paths to Unix-like paths
  2. Operate on the resulting Unix-like paths.

This is a good idea anyway, even if you are on Windows. You can perform the conversion using the path_slash crate, for instance.

Awesome! Thanks @chrisd and @H2CO3

Why do you say it's a good idea to do this on Windows?

Because only Windows presents the problem of two distinct path separator characters. Normalizing to the `nix form, which Windows accepts, resolves that particular discrepancy (of many) between Windows and other common OSes.

2 Likes