Surprising behaviour of Path.join

I have a:
let current_path:&Path = "/home";
let selected_item:String = "/tom";
let full_path = PathBuf::from(current_path.join(&selected_item));

full_path here will be after join /tom not as I would expect /home/tom.

What's going on?

This surprised me too, but it's documented behaviour:

From PathBuf in std::path - Rust

If path is absolute, it replaces the current path.

Note that "/tom" is an absolute path.

BTW join() returns a PathBuf already, so the PathBuf::from is not needed.

Hi, thanks for the reply.
Surely this API is poorly designed.
Anyway, so how to achieve joining those two paths together ?

Don't put a leading / in selected_item.

1 Like

It's the same reason why typing cd /tom in the /home moves you to the /tom not /home/tom

3 Likes

@alice
Hehe, sure, but it is there as it indicates a dir instead of just a file. I can surely remove that during the process of assembling the new path but that is something I would really like to avoid and have library do it for me. Is there a way to construct that new path just using rust types provided or do I really have to manually check for a char and if char is / remove it? This seems so C/C++, something that I wanted to avoid in Rust.

Generally, you would indicate a directory with a trailing slash rather than a leading slash.

Where do you get these paths from?

2 Likes

@alice
I'm working on file manager, something similar to mc.
But your comment about trailing slash made me think and perhaps I'll redesign so I have trailing slash not leading.
Thank you

Using trailing slashes for directories indeed sounds like the best solution here.

In general, I do not find Rust's behavior here problematic. Joining two absolute paths doesn't make that much sense.

3 Likes

Couldn't agree more!